React.memo issue with Redux



我有两个组件。

function Parent(props){
const handleClick = () => {
console.log(props.stateA);
};
return <div><Child text={stateB} handleClick={handleClick} /></div>
}
const mapStateToProps = (state) => {
return {
stateA: state.stateA // stateA will be changed somewhere else
stateB: state.stateB
}
};
export default connect(mapStateToProps)(Parent);
function Child(props) {
return <div onClick={props.handleClick}>{props.text}</div>
}
export default React.memo(Child,(prev, next) => {
return prev.text === next.text
});

我的问题是,当状态A在某个地方更改时,单击Child将记录以前的状态A。我无法访问最新的stateA。

你可以看到,当状态A改变时,我不想Child重新渲染,它应该只在状态B改变时重新渲染。但我想在单击Child时访问Parent中的最新状态A。

有什么方法可以解决这个问题吗?

如果Parent组件是功能组件,那么您可以像这样使用

const [valueA, setValueA] = useState('')
useEffect(() => {
setValueA(props.stateA)
},[props.stateA])
console.log(valueA) // latest Value of stateA
return <div><Child text={stateB} handleClick={handleClick} /></div>

我希望它对你有用。

您应该能够访问props.stateA,没有问题的

const handleClick = () => {
console.log(props.stateA);
};

因为你在handleClick中访问了父母的道具。因此,如果props.stateA过时,那么逻辑结论是父级没有收到最新的道具。我们可以看看你是如何更新道具/状态的吗?

您遇到的问题与Redux无关。

Parent组件将两个道具传递给子级:在需要时更改的文本和在Parent组件的每个渲染中更改的handleClick-每次都会创建一个新函数。

但是React.memo只检查文本道具,所以孩子经常收到一个过时的handleClick

正确的解决方案是用useCallback包装handleClick,并检查React.memo中的所有道具(默认情况下react会这样做(。

function Parent(props){
const handleClick = useCallback(() => {
console.log(props.stateA);
}, []);
return <div><Child text={stateB} handleClick={handleClick} /></div>
}
const mapStateToProps = (state) => {
return {
stateA: state.stateA // stateA will be changed somewhere else
stateB: state.stateB
}
};
export default connect(mapStateToProps)(Parent);
function Child(props) {
return <div onClick={props.handleClick}>{props.text}</div>
}
export default React.memo(Child);

您可以保留一个refstateA,这样它就是调用handleClick时记录的内容。useRef确保使用最后一个值。

function Parent(props){
const stateARef = useRef(props.stateA);
useEffect(() => {
stateARef.current = props.stateA;
}, [props.stateA])
const handleClick = () => {
console.log(stateARef.current);
};
return <div><Child text={stateB} handleClick={handleClick} /></div>
}

最新更新