繁体   English   中英

React 钩子 - 带有清理功能的 useEffect

[英]React hook - `useEffect` with clean up

我正在学习 React Hook 和useEffect ,但我可能没有掌握正确使用它的关键点。

我有以下情况:

  1. 如果用户切换下拉列表,将检查是否有来自全局 state 的isAnyChange标志,如果当前页面上有任何更新。
  2. 如果没有变化,会提前go重定向到下一页,
  3. 如果有任何变化,将显示一个确认对话框。

然后在确认对话框中,将有 2 个按钮:

  • 4.1 一个要求保存,检查验证和重定向,
  • 4.2 一个要求不保存和重定向。

我使用不同的useEffect包括上述逻辑,但我不确定我是否在做正确的方法,因为它看起来与我自己有关并使事情变得复杂,那么分解我的功能的最佳方法是什么? 我在这里通过使用那些local state flag来触发不同的useEffect来做正确的设计吗? 虽然我想不出任何更好的方法......

const pageComponent = props => {
   const [isSelectChange, setIsSelectChange] = useState(false);
   const [canRedirect, setCanRedirect] = useState(false);
   const [isSaveCompleted, setIsSaveCompleted] = useState(false);

   const anyChange = useSelector(state => return state.anyChange;);
   const anyValidError = useSelector(state => return state.anyValidError;);

   // step 1. dropdown change to change local state and trigger useEffect in step 2
   const selectChange = () => {
      setIsSelectChange(true);
   }

   // step 2. state isSelectChange to trigger step 3 howConfirmDialog or useEffect in step 6
   useEffect(() => {
     if (isSelectChange) {
        if (anyChange) { showConfirmDialog(); }
        else { setCanRedirect(); }
        // should I placed it here? but this seems to trigger the same useEffect a second time even though no code is executing 
        // setIsSelectChange(false);
     }

     return () {
        // clean up to reset the flag back to avoid looping here on isSelectChange, is it the right place to do it here?
        setIsSelectChange(false);
     }
   }, [isSelectChange])

   // step 3. dispatch a confirm dialog
   const showConfirmDialog() => {
      dispatch(openConfirmDialog(
        dialog: <ConfirmDialog confirmhdlr={saveAndRedirect} cancelhdlr={cancelAndRedirect} />
      );
   }

   // step 4.1 save and redirect
   const saveAndRedirect = async () => {
      await(savePage());
      // this is to trigger another useEffect monitoring on isSaveCompleted flag
      setIsSaveCompleted(true);
      setCanRedirect(true);
   }
   
   // step 4.2 cancel and redirect
   const cancelAndRedirect = () => {
      setCanRedirect(true);
   }
   
   // step 5. state isSaveCompleted to trigger
   useEffect(() => {
     if (isSaveCompleted && !anyValidError) {
        // this is to trigger another useEffect monitoring on "canRedirect"
        setCanRedirect(true);
        // should I placed it here? but this seems to trigger the same useEffect a second time even though no code is executing 
        // setIsSaveCompleted(false);
     }

     return () {
        // clean up to reset the flag back to avoid looping here on isSaveCompleted flag, is it the right place to do it here?
        setIsSaveCompleted(false);
     }
   }, [isSaveCompleted])

   // step 6. state canRedirect to trigger redirect
   useEffect(() => {
     if (canRedirect) {
       if (isSaveCompleted && !anyValidError) {
          // this is to trigger another useEffect monitoring on "canRedirect"
          setCanRedirect(true);
       }
       // should I placed it here? but this seems to trigger the same useEffect a second time even though no code is executing 
       // setCanRedirect(false);
     }

     return () {
        // clean up to reset the flag back to avoid looping here on canRedirect flag, is it the right place to do it here?
        setCanRedirect(false);
     }
   }, [canRedirect])

   return (<select onChange={selectChange}>)
}

如您所见,我有不同的标志来触发不同useEffect ,我可以在一个 function 中完成所有这些操作,那么为什么要在这里使用useEffect呢?

这不是答案,但它应该可以帮助您更好地理解钩子。 您有三个 useEffects,并且每次更改 ANY state 时,它们中的每一个都会起作用。 因此,您的第 1 步会触发下面的所有 useEffects。 像这样使用依赖项列表:

useEffect(()=>{
  ...
}, [isSelectChange]) // this hook fires only when isSelectChange state changes.

useEffect(()=>{
  ...
}, []) // this hook fires only once, when the component ie rendering for the very first time

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM