Open fayeah opened 4 years ago
hook是react16+的新特性,解决了逻辑复用等很多问题,使得我们能在函数是组件中使用state等特性。但是一旦用不好就很容易造成死循环。这里看2个例子以及如何解决。 根据文档: when you want some code to be executed after every render
以const [count, setCount] = useState(0)为例
const [count, setCount] = useState(0)
useEffect(() => { setCount(100); });
这个时候render正常
useEffect(() => { setCount(count+100); });
会发生无限的死循环情况,那是因为“By default, useEffect always runs after render has run”。意思是,每次render之后effect hook都会重新执行。所以上面死循环的步骤分解开来就是:
如果我们只想要count增加一次那么,加一个空的依赖即可
useEffect(() => { setCount(100); }, []);
对于有些情况,我们希望根据state的变化而执行useEffect hook,那么我们可以加响应的dependency
useEffect(() => { const getData = async () => { const response = await fetch(`https://xxxx/api/people/${props.id}/`); const newData = await response.json(); setData(newData); }; getData(); }, [props.id]);
这样就能解决死循环的问题,因为如果没有[props.id],跟上述死循环的逻辑是一样的。这样就能根据我们需要的id去获取,当id发生变化之后重新执行fetch的操作。
[props.id]
对于count的问题,尝试添加dependency,当count变化的时候再去执行 hook,但是还是有问题
const [count, setCount] = useState({a: 9}); useEffect(() => { setCount({a: 100}); }, [count]); return ( <div> <p>Count: {JSON.stringify(count)}</p> </div> );
那是因为对于引用类型object,每次都会产生新的id,那么相当于每次count都发生了变化,即便setCount的值看上去是静态数据。但是每次赋的值都是新的object。所以这个时候我们可以使用JSON.stringify(count)来解决:
object
const [count, setCount] = useState({a:0}); useEffect(() => { setCount({a: 100}); }, [JSON.stringify(count)]); return ( <div> <p>Count: {count.a}</p> </div> );
hook是react16+的新特性,解决了逻辑复用等很多问题,使得我们能在函数是组件中使用state等特性。但是一旦用不好就很容易造成死循环。这里看2个例子以及如何解决。 根据文档: when you want some code to be executed after every render
当没有dependency
以
const [count, setCount] = useState(0)
为例这个时候render正常
会发生无限的死循环情况,那是因为“By default, useEffect always runs after render has run”。意思是,每次render之后effect hook都会重新执行。所以上面死循环的步骤分解开来就是:
如何解决
如果我们只想要count增加一次那么,加一个空的依赖即可
对于有些情况,我们希望根据state的变化而执行useEffect hook,那么我们可以加响应的dependency
这样就能解决死循环的问题,因为如果没有
[props.id]
,跟上述死循环的逻辑是一样的。这样就能根据我们需要的id去获取,当id发生变化之后重新执行fetch的操作。添加了dependency还是有问题
对于count的问题,尝试添加dependency,当count变化的时候再去执行 hook,但是还是有问题
那是因为对于引用类型
object
,每次都会产生新的id,那么相当于每次count都发生了变化,即便setCount的值看上去是静态数据。但是每次赋的值都是新的object。所以这个时候我们可以使用JSON.stringify(count)来解决: