Dar*_*ren 1 javascript typescript reactjs react-hooks
I am having some troubles with useState when listening to history changes in useEffect.
When the pathname changes, setState is initiated but then the state is added back.
For example, I have a flag component that collects groups of notifications, but on the pathname change, I want all flags to be dismissed and removed from state.
The flag component
const PageFlag = ({ history }: InterfaceProps) => {
const { contextData, dismissFlag, dismissAllFlags } = useContext(GlobalConsumer);
useEffect(() => {
history.listen(() => {
dismissAllFlags();
});
});
return (
<>
<FlagGroup onDismissed={dismissFlag}>
{contextData.flags.map((flag, index) => (
<Flag key={index} {...flag} />
))}
</FlagGroup>
</>
);
};
Run Code Online (Sandbox Code Playgroud)
History prop is used from import { withRouter } from 'react-router-dom'
The state and function for dismissAllFlags is shown in a createContext component as
const DefaultState: InterfaceState = {
otherStateExample: false,
flags: []
};
export const GlobalConsumer = createContext({
contextData: DefaultState,
addFlag: (flagData: any) => {},
dismissFlag: () => {},
dismissAllFlags: () => {}
});
export const GlobalProvider = ({ children }: InterfaceProps) => {
const [state, setState] = useState<InterfaceState>({
...DefaultState
});
return (
<GlobalConsumer.Provider
value={{
contextData: state,
addFlag: (flagData: any) => {
setState({ ...state, flags: [flagData].concat(state.flags) });
},
dismissFlag: () => {
setState({ ...state, flags: state.flags.slice(1) });
},
dismissAllFlags: () => {
setState({ ...state, flags: [] });
}
}}
>
{children}
</GlobalConsumer.Provider>
);
};
Run Code Online (Sandbox Code Playgroud)
The problem arises, where on pathname change, dismissAllFlags uses setState to set flags as [] but then adds back the previous state with the flags.
How can I remove all flags but remember the current state for other items?
您缺少 on 的第二个输入参数useEffect(),这将导致在每次渲染时读取侦听器。
它应该是这样的,注意你也不应该需要内部函数。
useEffect(() => {
history.listen(dismissAllFlags)
}, []);
Run Code Online (Sandbox Code Playgroud)