Star Concent if you are interested in it, I will appreciate it greatly.
attention hook dependency
When we write the below code, eslint may tip us pass dependency if you want the component works well
function NormalDemo() {
const [count, setCount] = useState(0);
const dom = useRef(null);
useEffect(() => {
const cur = dom.current;
const add = () => setCount(count + 1);
cur.addEventListener("click", add);
}, []);
return <div ref={dom}>normal {count}</div>;
}
so we should add the count to dep-list
useEffect(() => {
// ...
}, [count]);
we should attention that in every render period, we add a event listener to the dom ref, but we forget to remove the ref's previous render period listener, so the right code should be like below
useEffect(() => {
// ...
cur.addEventListener("click", add);
return ()=> cur.removeEventListener("click", add)
}, [count]);
if we use concent, no traps any more
With concent setup
feature, and it supports class component and function component both, we can easily write the right code.
- define setup first
const setup = ctx=>{
const addCount = () => {
const count = ctx.state.count;
ctx.setState({count: count + 1});
}
// just like useEffect, but here no dependency
ctx.effect(()=>{
const cur = ctx.refs.dom.current;
cur.addEventListener('click', addCount);
return ()=>cur.removeEventListener('click', addCount);
}, []);
return { addCount }
}
- declare a class component
// or @register({setup, state:{count:0}})
@register({setup})
class ConcentClassDemo extends React.Component{
state = {count:0}
render(){
const {useRef, state, settings} = this.ctx;
// this.ctx.state === this.state
return (
<div>
<div ref={useRef('dom')}>class {state.count}</div>
<button onClick={settings.addCount}>add</button>
</div>
)
}
}
- declare a function component
function ConcentFnDemo() {
const {useRef, state, settings} = useConcent({setup, state:{count:0}});
return (
<div>
<div ref={useRef('dom')}>fn {state.count}</div>
<button onClick={settings.addCount}>add</button>
</div>
)
}
Just look the code above, you will find concent expose the 100% same api to class component and function component both, so it allow you switch component style whatever you want.
one more thing
If we want to do something when count change, how could we do? just put the key name is enough.
const setup = ctx=>{
ctx.effect(()=>{
//detect count changed in didMount or didUpdate
},['count']);
}
here is online demo
Top comments (0)