The examples here
https://threejs.org/examples/#webgl_animation_keyframes
seem to work great on my phone...
But very soon after Codesandbox made the switch to containers and started chasing monetization. I saw an interaction between the creators of each on Twitter at the time where Codesandbox promised not to throttle or limit R3Fs examples. But I don't think they fully kept that promise.
All the broken ones I saw were weird things like model/asset files just not being there at all.
Since they bring their own reconcile(a, b, diff) function to React, these libs can turn:
const world = new World()
const player = new Player()
world.add(player)
// somehow wire up the code to keep
// player.pos updated
Into: const [x, setX] = useState(0)
return <World>
<Player x={x} />
</World>
In other words, you write declarative code, and it does the hard imperative work of adding/removing/disposing/updating things for you.Just like how it helps you sync your data model to underlying stateful DOM nodes; the idea can be applied on top of any stateful system.
https://github.com/levicape/fourtwo
The best way to use template JSX is either with a CLI, or by using #! pragma to output the constructed yaml after using a builder.
I wonder if there’s any research (PL or maybe even more philosophical) on whether declarative approaches can logically cover all imperative use cases.
Basically: is there something special about “verbs” (imperative) that let you do things that “nouns” (declarative) cannot, at least within reasonable verbosity constraints?
SwiftUI has failed pretty much all of those for me.
In react-pixi / react-three, you have your declarative component tree alongside a `useTick`/`useFrame` function that you can use to do more surgical work, and it works well together. Each component can tap into the tick to update itself.
const Enemy = ({ initalPos, size }) => {
const [pos, setPos] = useState(initialPos)
useTick(dt => {
setPos(/* Move in a circle */)
})
return <Sprite
src="/enemy.png"
size={size}
pos={pos}
/>
}
I've migrated a few medium-sized pixi/three projects to their React wrappers, and the code cleaned up so well that I could work on them again.Before that, I'd tried modeling games in Elm and then using its port system to send the game state to JS which then updates the pixi/three world. But it's exactly this updateWorld(oldWorld, newState) that's hard to write, yet that's what these libs do for you.
But you can actually see this dichotomy in template libraries, they usually have constructs making them fully Turing-complete (loops, conditionals, etc).
For instance, Solid also supports custom JSX renderer, but doesn’t use a VDOM to achieve that.
I find it helpful to think of JSX as analogous to a macro (in the lispy sense of the term), except that its syntax and implementation are decoupled. Most compiler tooling assumes the implementation maps to a function call, but even that isn’t strictly required (and again, Solid is a counter example).
When all you know is React, everything gets viewed through that limited lens.
The point is about the declarative abstraction and how it's useful for people who don't know what "React Three" might entail, not to enumerate all the frameworks that have it under a submission about "React Three Ecosystem".
Babel has a pragma property, and esbuild allows you to pass it in the command line: `--jsx-factory=h`.
https://esbuild.github.io/content-types/#auto-import-for-jsx
Experientially, typescript still has a bit of trouble figuring out the right types for these nested structures. Even with a typed jsx function it sometimes doesn’t infer correctly, so providing plugin capability would take a very careful hand
https://r3f.docs.pmnd.rs/advanced/pitfalls#avoid-setstate-in...
To fix this, they suggest using useRef and manually updating the object. But then your code ends up just as complicated, if not more so, than if you had just stuck with vanilla three.js.
React code looks great, the dev experience is fantastic. But user experience sometimes less so. Hooks kind of hide what’s going on.
State should basically only be used as "keyframes"
If the only tool you have is React everything around you start looking remarkably similar to JSX.
Taking a quick look at [the docs](https://r3f.docs.pmnd.rs/getting-started/introduction) linked above, I see the use of Canvas. Fair enough.
I start using X3D at work in order to enable some cool functionality showing steps to build an assembly in 3D, and it's actually insane how high the performance is. It's all HTML components, so I wrote a super thin React wrapper (essentially the scene needs to be manually loaded once, that's about all) and have been cruising with that.
Effortless to fly, rotate, hide or highlight parts, decompose things into x3d assets, and so on.
It might have issues somewhere, I haven't widely tested browser compat or anything, but it's curious to me how little I see it versus how much I see ThreeJS when it seems that X3D is the more capable platform.
GP - are we misunderstanding something here?
It uses a virtual DOM to diff the desired state and the current one: https://shopify.github.io/react-native-skia/docs/canvas/cont...
If you're interested how it's implemented, that's the source code: https://github.com/Shopify/react-native-skia/blob/main/packa...
I found Threlte[1] recently and enjoy not having to write low-level Three.js code to make things happen.
---
[1]: https://threlte.xyz
tlarkworthy•1mo ago
[1] https://threejs.org/
jasonjmcghee•1mo ago
I understand why people like the declarative nature of react three fiber, but it's quite unfortunate that it requires something like code sandbox to allow modification / working with it on the web- but that's by nature due to being react.
Vanilla three.js can be written surprisingly similarly, if you are disciplined about breaking things up into functions/components. And no react necessary / can embed a code editor and allow direct modification.
eyelidlessness•1mo ago
It’s doesn’t have to be especially onerous discipline if you embrace it, but it becomes considerably more onerous as it becomes more social: if some members of a team/contributors to a project embrace it more/less than others, that difference in commitment becomes a constant source of friction.
mikebelanger•1mo ago
That's one of the stronger arguments for opinionated pre-processors/frameworks/libraries like Typescript/TSX/JSX/React in general. Because it abstract away those things that only some team members would embrace, you effectively make everyone embrace them. That leads to less friction.
But this reduced friction comes at a cost: more complex abstractions and incidental bugs related to that complexity. And as far as the procedural vs declarative: after a certain degree of complexity, I find myself introducing procedural codes within useEffects, useMemos anyways
ttfkam•1mo ago
https://threlte.xyz/
throwaway314155•1mo ago