hookstate
hookstate copied to clipboard
Support useState "type" changes on component re-use
Use Case: I want to be able to have a component which can take either a boolean or a State
This is an abbreviated reproduction (i believe, untested) of a component which includes Modal, but the props changed depending on the context. The error appears to be that inside the Modal instance, useState() will ALWAYS expect a State
index.js:1120 Uncaught TypeError: Cannot read property 'get' of undefined
at useSubscribedStateMethods (index.js:1120)
at useState (index.js:112)
Example:
function Modal({state}:{state:boolean | State<boolean>}){
const scopedOpen = useState(open && typeof open !== 'boolean' ? open : false);
return <></>;
}
function MyComponent({enable}:{enable: boolean}){
const popup = useState(true);
if(enable){
return <Modal state={popup} />;
}else{
return <Modal state={false} />;
}
}
To work around this, I have to use an explicit key on the Modals in order destroy the shared state:
function Modal({state}:{state:boolean | State<boolean>}){
const scopedOpen = useState(open && typeof open !== 'boolean' ? open : false);
return <></>;
}
function MyComponent({enable}:{enable: boolean}){
const popup = useState(true);
if(enable){
return <Modal state={popup} key="state" />;
}else{
return <Modal state={false} key="primitive" />;
}
}
I'd would be great if either:
A) We should a more helpful error message that this isn't possible B) We detect the change and replace the shared state, but perhaps this a smell?
Hmm.. this is an interesting scenario and I am afraid it would be impossible to support it as the underlying "React.useState" would not support secondary data reinitialization. You are right, the key
is the only way to force React to reset the state. So, (B) is not an option. (A) could be an option, but probably under development mode only as I am not sure how efficient it would be do this checking. I will leave the ticket open until I could find time to add this check. Or feel free to experiment and suggest a solution for check.
This will become possible in Hookstate-4
Hi, I have most of necessary bits to implement this corner case in Hookstate 4, but I need help for this one. Would you be able to write unit tests for this one? And I will try to match the tests spec in Hookstate code....
Unfortunately this kind of use case is very hard to support. We decided to block it and throw an error when such a case is detected.