3 ms·
useState is a memoization technique and an abstraction to hide global state. You can do: let _count = 0; function Component() { return (
by lxe 7y ago
useState is a memoization technique and an abstraction to hide global state. You can do:
let _count = 0;
function Component() {
return (
<div>
<div>{_count}</div>
<button onClick={() => { _count++; render(); }}>Increase</button>
</div>
);
}
function render() {
React.render(<Component />, root)
}
Or you can abstract it:
let _count;
function useCount(initialValue) {
return [_count, (value) => { _count = value; render(); }]
}
function Component() {
const [count, setCount] = useCount(0);
return (
<div>
<div>{count}</div>
<button onClick={() => setCount(count + 1)}>Increase</button>
</div>
);
}
And then generalize it and make each state dependent on the order of useState calls:
const states = [];
function useState(initialValue) {
const state = states.shift() || { value: initialValue }; // Pop or create
setTimeout(() => states.push(state), 0); // Defer the push
return [state.value, (value) => { state.value = value; render(); }];
}
function Component() {
const [count, setCount] = useState(0);
const [name, setName] = useState('World');
return (
<div>
<div>{count}</div>
<button onClick={() => setCount(count + 1)}>Increase</button>
<h1>Hello {name}</h1>
<input value={name} onChange={(e) => setName(e.currentTarget.value)} />
</div>
);
}
Actual hooks also track the component that's being rendered, and don't just call the global render function, but that's pretty much the whole useState implementation.
Here's a codepen: https://codepen.io/lxe/pen/RwbXPKo https://codepen.io/lxe/pen/RwbXPKo
- scient 7y agoFor a developer who has not done React before - this looks super convoluted for some reason. Global functions with constants defined in another function, that act as ... methods? I'm lost :D
- lxe 7y agoGlobal functions? It's just an example -- real world applications are more complicated.
- leowoo91 7y agoDoes that render() call in the useState function would still render the changed elements only?
- lxe 7y agoNo, render is global in this example. If you need to only render the component wrapping the useState, you have to track the caller (See https://github.com/facebook/react/blob/master/packages/react-reconciler/src/ReactFiberHooks.js#L169-L178 https://github.com/facebook/react/blob/master/packages/react...)
- leowoo91 7y agoThat is interesting, earlier I enabled flash painting in your codepen and it only re-rendered/flashed the specific component that has a value changed. Maybe that was a browser feature (safari) I will look into tracking to understand what you mean.. (or maybe it's a coincidence it works as expected)
- nohuhu 7y ago(shameless plug!) ... or you can use something like Statium's ViewModel, which is basically a hierarchically linked, locally scoped state container component: https://github.com/riptano/statium https://github.com/riptano/statium RealWorld example: https://github.com/nohuhu/react-statium-realworld-example-app https://github.com/nohuhu/react-statium-realworld-example-ap... Sorry... Just... Couldn't... :)