我从React钩子那里经历过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步)首先运行效果->登录'did mount ran:0'。然后将值1分配到存储
(第2步)第二个效果在-> log'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 :(得分:4)
您的两个调度都在第一次渲染之后被调用,因此即使您的第二个渲染值是0之前,您的第二个useEffect也将无法检测到变化,因为没有变化。
让我们看看您的渲染方法中发生了什么
首次渲染:
a = 0
首次使用效果:dispatch({a:1})
第二次useEffect:dispatch({a:0})
现在在您的redux存储中,a为0。
第二次渲染
a = 0
第一次useEffect:由于没有依赖项而无法运行
第二次useEffect:不会随着汉斯的更改而运行。
答案 1 :(得分:1)
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
...由reducer在存储中处理,但结果相同。a
did mount: 0
//'旧'a
1
...在redux存储中更改状态 ....呈现的文本0
...
...
// useSelector
强制重新呈现-检测到更改
render: 1
//最新的调度值,由减速器处理为新状态,由选择器重新读取use effect: 1
// useEffect
由于a
的变化而按预期工作 1
...
...
当然,从其他组件进行分派将强制在此组件中进行更新...如果值将不同。