react-tracked
react-tracked copied to clipboard
How to get the original state
Hi, I've recently experienced an issue with React Track. Perhaps its more about understanding the library and proxies than a real problem but – In some cases I want to have the up to date context event if it's not rendered in current component. For example in useEffect hook or events. Hence an onClick event in PersonFamilyName. It will always give me an "old" value of firstName. How can I get up to date context in this circumstances?
import React, {
useReducer,
useRef,
useEffect,
Reducer,
} from 'react';
import { createContainer, getUntrackedObject } from 'react-tracked';
const initialState = {
firstName: 'Harry',
familyName: 'Potter',
};
type State = typeof initialState;
type Action =
| { type: 'setFirstName'; firstName: string }
| { type: 'setFamilyName'; familyName: string };
const reducer: Reducer<State, Action> = (state, action) => {
switch (action.type) {
case 'setFirstName':
return { ...state, firstName: action.firstName };
case 'setFamilyName':
return { ...state, familyName: action.familyName };
default:
throw new Error('unexpected action type');
}
};
const { Provider, useTracked } = createContainer(
() => useReducer(reducer, initialState),
{ concurrentMode: true },
);
const PersonFirstName = () => {
const [state, dispatch] = useTracked();
const renders = useRef(1);
useEffect(() => {
renders.current += 1;
});
return (
<div>
First Name: {Math.random()}
<input
value={state.firstName}
onChange={(event) => {
dispatch({ type: 'setFirstName', firstName: event.target.value });
}}
/>
(renders:{renders.current})
</div>
);
};
const PersonFamilyName = () => {
const [state, dispatch] = useTracked();
const renders = useRef(1);
useEffect(() => {
console.log("Test FamilyName")
renders.current += 1;
});
return (
<div>
Family Name: {Math.random()}
<button onClick={() => {
console.log("I want to get the actual state", state.firstName)
console.log("I want to get the actual state", getUntrackedObject(state))
}}>Click</button>
<input
value={state.familyName}
onChange={(event) => {
dispatch({ type: 'setFamilyName', familyName: event.target.value });
}}
/>
(renders:{renders.current})
</div>
);
};
const ReactTracked = () => (
<Provider>
<PersonFirstName />
<PersonFamilyName />
</Provider>
);
export default ReactTracked;```
In some cases I want to have the up to date context event if it's not rendered in current component.
I don't think it's an issue with react-tracked. It's how useState
(useReducer
) works. I mean, it will behave the same with bare context.
What you want is probably a "global state" and in such cases, you may want to try zustand
(with or without react-tracked), or jotai
, or valtio
.
Closing as stale.