有多种使用效应时跳过首先使用效果

  • 本文关键字: reactjs react-hooks
  • 更新时间 :
  • 英文 :


限制了在我们可以做的第一个渲染上运行的使用效果:

  const isFirstRun = useRef(true);
  useEffect (() => {
    if (isFirstRun.current) {
      isFirstRun.current = false;
      return;
    }
    console.log("Effect was run");
  });

根据示例:https://stackoverflow.com/a/53351556/3102993

但是,如果我的组件具有多种用途效果,哪个都处理不同的使用情况?我已经尝试在另一个使用效果中使用isFirstRun.current逻辑,但是由于一个返回,另一种仍在初始渲染上运行。

一些上下文:

const Comp = () => {
const [ amount, setAmount ] = useState(props.Item ? Item.Val : 0);
const [ type, setType ] = useState(props.Item ? Item.Type : "Type1");
useEffect(() => {
    props.OnAmountChange(amount);
}, [amount]);
useEffect(() => {
    props.OnTypeChange(type);
}, [type]);
return {
    <>
        // Radio button group for selecting Type
        // Input field for setting Amount
    </>
}
}

我对每种都使用单独使用效果的原因是因为如果我执行以下操作,则不会更新金额。

useEffect(() => {
    if (amount) {
        props.OnAmountChange(amount);
    } else if (type) {
        props.OnTypeChange(type)
    }
}, [amount, type]);
据我所知,

您需要控制第一个安装和连续的Rerenders上使用效率逻辑的执行。您想跳过第一个使用效果。效果在组件的渲染之后运行。

因此,如果您使用此解决方案:

const isFirstRun = useRef(true);
  useEffect (() => {
    if (isFirstRun.current) {
      isFirstRun.current = false;
      return;
    }
    console.log("Effect was run");
  });
   useEffect (() => {
    // second useEffect
    if(!isFirstRun) {
        console.log("Effect was run");
     }
   
  });

因此,在这种情况下,一旦isfirstrun ref设置为false,因为所有连续的效果isfirstrun的值变为false,因此所有人都将运行。

您可以做的是,使用诸如Usemount自定义钩子之类的东西,它可以告诉您是第一个渲染还是连续的Rerender。这是示例代码:

const {useState} = React
function useMounted() {
  const [isMounted, setIsMounted] = useState(false)

  React.useEffect(() => {
    setIsMounted(true)
  }, [])
  return isMounted
}
function App() {

  const [valueFirst, setValueFirst] = useState(0)
  const [valueSecond, setValueSecond] = useState(0)
  const isMounted = useMounted()
  //1st effect which should run whenever valueFirst change except
  //first time
  React.useEffect(() => {
    if (isMounted) {
      console.log("valueFirst ran")
    }
  }, [valueFirst])

  //2nd effect which should run whenever valueFirst change except
  //first time
  React.useEffect(() => {
    if (isMounted) {
      console.log("valueSecond ran")
    }
  }, [valueSecond])
  return ( <
    div >
    <
    span > {
      valueFirst
    } < /span> <
    button onClick = {
      () => {
        setValueFirst((c) => c + 1)
      }
    } >
    Trigger valueFirstEffect < /button> <
    span > {
      valueSecond
    } < /span> <
    button onClick = {
      () => {
        setValueSecond((c) => c + 1)
      }
    } >
    Trigger valueSecondEffect < /button>
    <
    /div>
  )
}
ReactDOM.render( < App / > , document.getElementById("root"))
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.8.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.8.3/umd/react-dom.production.min.js"></script>
<div id="root"></div>

我希望它有帮助!

您可以使用单个使用效果来完成这两个效果,您刚刚实现了逻辑。

您的原始尝试:

useEffect(() => {
  if (amount) {
      props.OnAmountChange(amount);
  } else if (type) {
      props.OnTypeChange(type)
  }
}, [amount, type]);

这里的问题是if/elseif,将其视为独立效果:

useEffect(() => {
  if (amount !== 0) props.onAmountChange(amount);
  if (type !== "Type1") props.onTypeChange(type);
}, [amount, type])

在此方法中,如果值与原始值不同,则将调用"更改"。但是,这有一个错误,因为如果用户将值切换回默认值,则它将无法正常工作。因此,我建议这样做这样的整个代码:

const Comp = () => {
  const [ amount, setAmount ] = useState(null);
  const [ type, setType ] = useState(null);
  useEffect(() => {
    if (amount !== null) {
      props.onAmountChange(amount);
    } else {
      props.onAmountChange(0);
    }
  }, [amount]);
  useEffect(() => {
    if (type !== null) {
      props.onTypeChange(type);
    } else {
      props.onTypeChange("Type1");
    }
  }, [type]);
  return (
    <>
        // Radio button group for selecting Type
        // Input field for setting Amount
    </>
  )
}

通过使用null作为初始状态,您可以延迟调用props方法,直到用户在无线电中设置更改状态的值。

如果您使用的是检查ISFIRSTRUN的多个使用效果,请确保只有最后一个(底部(将ISFIRSTRUN设置为false。React会按顺序进行使用!

信用@dror bar评论来自React-Hooks的评论:Skip首次运行

相关内容

  • 没有找到相关文章

最新更新