[英]Using useState hook in useEffect on history.listen
在收听useEffect
的history
变化时,我在使用useState
时遇到了一些问题。
当pathname
更改时,会启动setState
,但随后会添加回state
。
例如,我有一个收集通知组的flag
组件,但是在pathname
更改时,我希望所有标志都被解除并从state
中删除。
标志组件
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>
</>
);
};
历史道具用于import { withRouter } from 'react-router-dom'
用于dismissAllFlags
的 state 和 function 在createContext
组件中显示为
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>
);
};
问题出现了,在pathname
更改时, dismissAllFlags
使用setState
将flags
设置为[]
但随后将先前的 state 与flags
添加回来。
如何删除所有flags
但记住其他items
的当前state
?
您缺少useEffect()
上的第二个输入参数,这将导致在每次渲染时都读取侦听器。
它应该看起来像这样,注意你也不应该需要内部 function。
useEffect(() => {
history.listen(dismissAllFlags)
}, []);
我们像这样使用它:
const [isOpen, setIsOpen] = useState(false);
useEffect(() => {
history.listen(() => setIsOpen(false));
}, [history]);
如果我明白你的要求是这样的:
您想将标志设置为空数组,而不必使用您当前正在执行的扩展方法添加先前的值
{...state, flags: []}
。
好吧,使用useState
是不可能的,您应该注意嵌套的 state 对象,因为使用较大的对象进行克隆可能会变得昂贵。 也许这就是你在这里试图避免的。
即使您切换到useReducer
,您最终仍会为 state 进行道具传播。
也许您应该将标志作为自己的 state const [flags, setFlags] = useState([])
或查看immutable-helper 。
此外,尽量尊重react-hooks/exhaustive-deps
otherwives 有趣的事情可能会开始发生。 如果没有部门,那么至少给你的钩子一个空数组以确保它执行一次。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.