-
-
Notifications
You must be signed in to change notification settings - Fork 98
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Bug?: useComputed doesn't update when given a new signal #366
Comments
Hey, this feels similar to #361 (comment), we should def document that! Thank you for calling this out. Basically this |
@JoviDeCroock I suppose that if Preact's signals are to be widely-used, some conventions should emerge. Such as, if a library exposes a component that takes signals as props, whose responsibility is to wrap them in It would also probably be useful to add the currently buggy uses of signals to tests so it can be verified that the problem is solved. |
And it also gets me thinking, I haven't experimented as much with (Just thinking out loud) |
@JoviDeCroock does this also work if we have a global state and we are using the |
main feature of |
But I don't think it's a good idea. I think it's better to have convention that you should provide stable signal refference into child component. Or if you can't - change child component key |
Btw, here is my hook that solve the issue Here is fixed example: |
@XantreGodlike Will this hook work in react? |
@noopurphalak All library work both in react and preact. This hook too |
@XantreGodlike I am asking specifically for state derived from |
If you will change reference of signal in context provider - it will rerender bottom components, but signal in |
@XantreGodlike Would you recommend defining signals and effects in a new JS file and exporting the signals to be used by multiple files instead of passing it to the Context API? |
If you're using Context for dependency injection it will work just fine. If you will do like this. const Ctx = createContext(null)
const Child = () => {
const sig = useContext(Ctx)
// will not update, will be 2
return useComputed(() => sig.value)
}
const A = () => {
const sig1 = useSignal(1)
const sig2 = useSignal(2)
const useFirst = useSignal(false)
return (
<Ctx.Provider value={useFirst.value ? sig1 : sig2}>
<Child />
</Ctx.Provider>
)
} |
So how do I get the updated state from useContext for useComputed or useSignalEffect to work? Is there any way to subscribe to signal changes in those hooks? |
import { useLinkedSignal } from '@preact-signals/utils/hooks'
const Child = () => {
const sig = useLinkedSignal(useContext(Ctx))
return useComputed(() => sig.value)
} |
I still don't understand the significance of I have a global state defined in import { signal, effect, computed } from "@preact/signals-react";
export function createAuthState() {
const authState = signal({
userUUID: ""
});
const isLoggedIn = computed(() => !!authState.value.userUUID);
return { authState, isLoggedIn };
} Now I am passing the above state in the Context API as shown below: <AuthContext.Provider value={createAuthState()}>
<ConfigProvider theme={theme}>
<App />
</ConfigProvider>
</AuthContext.Provider> In my state = useContext(AuthContext)
const updateState = (uuid) => {
state.authState.value = {
userUUID: uuid
}
} I also have a useSignalEffect(() => {
if (state.isLoggedIn.value) navigate("/dashboard")
}) This Please suggest a solution to this if possible. |
Don't create state at every render <AuthContext.Provider value={useMemo(() => createAuthState(), [])}>
<ConfigProvider theme={theme}>
<App />
</ConfigProvider>
</AuthContext.Provider> |
I tried that, still doesn't work |
I'm facing the same problem as @noopurphalak. I have a signal and a computed signal globally shared via context, both created using useSignal and useComputed, but updating signals does not trigger the computed one "@preact/signals-react": "^2.0.0", |
I'm wondering if this is intended behavior or not.
Steps to preroduce:
So it seems that
useComputed
can only start tracking a new signal when the previous one changes. If this is intended, it should be very well documented that you need to pass the same instance of the signal to get proper behavior.The text was updated successfully, but these errors were encountered: