[英]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.