[英]useEffect not working when dependency value changed
我从 React hook 体验过 useEffect 函数。 当我将它与 React-redux 的 useSelector 一起使用时,它工作得非常奇怪。
const initialState = { a: 0 };
function mainReducer(state = initialState, action) {
const { type, payload } = action;
switch (type) {
case 'A': return { ...state, a: payload }
default:
return state;
}
}
function MyComponent(props) {
const { a } = useSelector(state => state.mainReducer);
const dispatch = useDispatch();
useEffect(() => {
console.log('did mount: ', a);
dispatch({ type: 'A', payload: 1 })
}, []);
useEffect(() => {
console.log('use effect: ', a);
dispatch({ type: 'A', payload: a });
}, [a])
return (<View style={styles.container}>
<Text style={styles.text}>{a}</Text>
</View>);
};
日志:
did mount ran: 0
useEffect ran: 0
最后的结果是变量 'a' = 0
据我了解,在第一次渲染之后,这两种效果都按照代码中的顺序依次运行。
(步骤 1) 所以第一个效果 run fist -> log 'did mount ran: 0'。 然后它调度值 1 来存储
(步骤 2)第二个效果运行 -> 记录 'did mount ran: 0'。 然后它调度值 0 来存储
但我不明白的是,第二个效果必须跟踪变量“a”的变化,所以会有:
在以下渲染时间:
(第 3 步)当值“a”从 0 变为 1(从第 1 步开始)时,应该运行第二个 useEffect。
进而:
(第 4 步)当值再次从 1 变为 0 时(从第 2 步开始),它应该进行第三次重新渲染
所以日志应该是:
did mount ran: 0
useEffect ran: 0
useEffect ran: 1
useEffect ran: 0
你能向我解释一下我错过了什么吗? 谢谢
您的两个调度在第一次渲染之后被调用,因此即使在您的第二个渲染值为 0 之前,您的第二个 useEffect 将无法检测到变化,因为没有变化。
让我们看看渲染方法中发生了什么
第一次渲染:
一 = 0
第一个 useEffect: dispatch({ a : 1 })
第二个 useEffect: dispatch({ a : 0 })
所以现在在你的 redux store 中 a 是 0。
第二次渲染
一 = 0
first useEffect: 不运行,因为没有依赖
第二个 useEffect: 不会因为 hans's 没有改变而运行。
useSelector(state => state.mainReducer);
没有任何意义
应该有一个简单的状态转换(子选择)
const a = useSelector(state => state.a)
直接取自 redux 文档:
const counter = useSelector(state => state.counter)
你可以看到效果(从商店变化)略有变化的组件
function MyComponent(props) {
const a = useSelector(state => state.a);
const dispatch = useDispatch();
console.log('render: ', a);
useEffect(() => {
console.log('use effect: ', a);
dispatch({ type: 'A', payload: a });
}, [a])
useEffect(() => {
console.log('did mount: ', a);
dispatch({ type: 'A', payload: 1 })
}, []);
return (<View style={styles.container}>
<Text style={styles.text}>{a}</Text>
</View>);
};
它应该导致日志:
render: 0
// 初始状态use effect: 0
// 第一个效果运行0
... 在 store 中被 reducer 处理,但结果是相同的状态 ...a
在渲染开始时从状态中读取did mount: 0
// '旧' a
1
... 在 redux 存储中改变状态 .... 渲染文本0
...
...
// useSelector
强制重新渲染 - 检测到更改
render: 1
// 最新调度的值,由reducers 处理成新状态,由选择器重读use effect: 1
// useEffect
作品如预期的效果a
变化1
...
...
当然,来自其他组件的调度将强制在该组件中进行更新......如果值会不同。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.