Enr*_*ent 4 reactjs react-hooks
我在组件内部设置了一个效果,如果另一个状态属性发生更改,该效果也会更改视图。但是由于某种原因,即使安装了该组件,该组件的效果仍会运行,即使的值detailIndex没有更改。
const EventsSearchList = () => {
const [view, setView] = useState('table');
const [detailIndex, setDetailIndex] = useState(null);
useEffect(() => {
console.log('onMount', detailIndex);
// On mount shows "null"
}, []);
useEffect(
a => {
console.log('Running effect', detailIndex);
// On mount shows "null"!! Should not have run...
setView('detail');
},
[detailIndex]
);
return <div>123</div>;
};
Run Code Online (Sandbox Code Playgroud)
为什么会这样呢?
更新:如果不清楚,我正在尝试的是在组件更新时运行效果,因为detailIndex更改了。挂载时不行。
就我而言,即使我在 useEffect() 中使用了第二个参数,组件也会不断更新,并且我正在打印该参数以确保它没有改变,也没有改变。问题是我正在使用 map() 渲染组件,并且在某些情况下键发生了变化,如果键发生了变化,对于 react 来说,它是一个完全不同的对象。
确保代码useEffect仅在依赖项发生更改时运行,而不是在初始安装(第一次渲染)时运行的一种方法是分配一个最初false且仅true 在第一次渲染后才变为的变量,并且该变量自然应该是一个hook,因此它将在组件的整个生命周期内被记住。
useEffect:const {useEffect, useRef, useState} = React\n\nconst App = () => {\n const mountedRef = useRef() // \xe2\x86\x90 the "flag"\n const [value, setValue] = useState(false) // simulate a state change \n \n\n // with the trick\n useEffect(() => {\n if (mountedRef.current){ // \xe2\x86\x90 the trick\n console.log("trick: changed")\n }\n }, [value])\n\n\n // without the trick\n useEffect(() => {\n console.log("regular: changed")\n }, [value])\n\n\n // fires once & sets "mountedRef" ref to "true"\n useEffect(() => {\n console.log("rendered")\n mountedRef.current = true\n // update the state after some time\n setTimeout(setValue, 1000, true)\n }, [])\n \n return null\n}\n\nReactDOM.render(<App/>, document.getElementById("root"))Run Code Online (Sandbox Code Playgroud)\r\n<script crossorigin src="https://unpkg.com/react@16/umd/react.development.js"></script>\n<script crossorigin src="https://unpkg.com/react-dom@16/umd/react-dom.development.js"></script>\n<div id="root"></div>Run Code Online (Sandbox Code Playgroud)\r\nuseEffect默认情况下,React Hooks中的from from Hooks在每个渲染上执行,但是您可以在函数中使用第二个参数来定义何时再次执行效果。这意味着该功能始终在安装时执行。根据您的情况,第二个useEffect将在启动时以及detailIndex更改时运行。
更多信息:https://reactjs.org/docs/hooks-effect.html
资源:
有经验的JavaScript开发人员可能会注意到,传递给useEffect的函数在每个渲染器上都会有所不同。[...]如果在重新渲染之间某些值未更改,您可以告诉React跳过应用效果。为此,请将数组作为可选的第二个参数传递给useEffect:[...]
您可以添加第二个守卫,检查 detailIndex 是否已从初始值更改为 -1
useEffect(
a => {
if(detailIndex != -1)
{ console.log('Running effect', detailIndex);
// On mount shows "null"!! Should not have run...
setView('detail');
}},
[detailIndex]);
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
7679 次 |
| 最近记录: |