Suggestion for imperative update api
See original GitHub issueI’m finding this to be a very common pattern I’m using to avoid having react-three-fiber recreate new geometry for objects I need to regularly update. I’m wondering if there’s a nicer api for this.
Let’s say I’m creating a dynamic cube. I regularly do the following:
- I will create store with its dimensions
- create geometry and mesh instance, cached in the store
- have a memoised / reactive function that updates the geometry / mesh based off the cube dimensions
- apply the updated mesh to the primitive tag
class CubeStore {
@observable x = 0
@observable y = 0
@observable z = 0
constructor(x,y,z) {
this.x = x
this.y = y
this.z = z
this._geometry = getCubeGeometry(x,y,z)
}
@computed get geometry() {
const geometry = this._geometry
geometry.addAttribute('position', getCubeVertices(this.x, this.y, this.z))
geometry.attributes.position.needsUpdate = true
geometry.computeBoundingSphere()
return geometry
}
}
const geometry = ({cube}) => {
return <primitive object={cube.geometry} />
}
I’m ending up with a lot of code in my stores which I feel should be in the component. And I know you can’t avoid creating new instances because of the nature of three.js. But what I’m thinking is maybe if the component could have an update function, which react-three-fiber could use instead of reinstantiating the object on render.
Something like this would keep that logic inside the component and feels a little nicer:
class CubeStore {
@observable x = 0
@observable y = 0
@observable z = 0
constructor(x,y,z) {
this.x = x
this.y = y
this.z = z
}
}
const geometry = ({cube}) => {
ref = useRef()
// use this on update instead of creating a new geometry instance
useImperativeUpdate(
() => {
const geometry = ref.current
geometry.addAttribute('position', getCubeVertices(cube.x, cube.y, cube.z))
geometry.attributes.position.needsUpdate = true
geometry.computeBoundingSphere()
},
[cube.x, cube.y, cube.z] // execute only if these change
)
return <bufferGeometry ref={ref} ... />
}
What’s your thoughts on something like that?
Issue Analytics
- State:
- Created 5 years ago
- Reactions:1
- Comments:15 (15 by maintainers)
Top Results From Across the Web
Declarative APIs in an Imperative World - InfoQ
In this example, we only want to update if a panel is being hidden or shown. We don't care about those other props....
Read more >Naming conventions | Cloud APIs
The verb portion of the method name should use the imperative mood, which is for orders or commands rather than the indicative mood...
Read more >Apollo Client's new imperative store API - Apollo GraphQL Blog
Apollo Client's new imperative store API ... These methods allow you to update the data in your local cache, to simulate an update...
Read more >Hooks API Reference - React
useEffect. useEffect(didUpdate); Accepts a function that contains imperative, possibly effectful code. Mutations, subscriptions, timers, logging, and other ...
Read more >Add Imperative Slot API by mfreed7 · Pull Request #966 - GitHub
This is a fresh PR, with updates from #860. I don't have permissions to update that PR, and the master-to-main transition made it...
Read more >
Top Related Medium Post
No results found
Top Related StackOverflow Question
No results found
Troubleshoot Live Code
Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free
Top Related Reddit Thread
No results found
Top Related Hackernoon Post
No results found
Top Related Tweet
No results found
Top Related Dev.to Post
No results found
Top Related Hashnode Post
No results found

useImperativeUpdate is a nice idea btw, it could still be useful.
I don’t see how yours would work, you don’t pass a ref. It could return one maybe?
Or, accept one as the 3rd param optionally, so that you can re-use refs for multiple purposes
There was indeed a bug, onUpdate was called too early.