我正在尝试使用由usePrevious
钩子制作的自定义钩子useRef
比较旧状态值和新状态值,其中状态由对象数组组成。
在打印旧值和当前值时,在两种情况下都将返回当前值,但是当它只是数字数组或如果是第一个渲染时,它将很好地工作。
此外,https://codesandbox.io/s/4c4ie是测试的代码。
我有没有犯过任何错误,或者还有其他事情要做以恢复旧状态和当前状态?
下面是我正在使用的代码。
import React from 'react'
function usePrevious(value) {
const ref = React.useRef();
React.useEffect(() => {
ref.current = value;
});
return ref.current;
}
function Playground() {
const [state, setState] = React.useState([{ value: 0 }]);
const prevState = usePrevious(state);
React.useEffect(() => {
console.log(prevState, state)
if (prevState !== state) {
try {
console.log(prevState[0].value)
console.log(state[0].value)
} catch (e) {
}
}
}, [JSON.stringify(state)])
// }, [state])
const _onClick = () => {
const tempState = [...state];
tempState[0].value = state[0].value + 1;
setState(tempState)
}
return (
<div>
<div>prevStateValue: {prevState ? prevState[0].value : 'undefined'}</div>
<div>stateValue: {state[0].value}</div>
<button onClick={_onClick}>click</button>
</div>
)
}
export default Playground
答案 0 :(得分:1)
您正在使用tempState[0].value = state[0].value + 1;
这是一个有效的代码段:
function usePrevious(value) {
const ref = React.useRef();
React.useEffect(() => {
ref.current = value;
},[value]);//only set when value changed
return ref.current;
}
function App() {
const [state, setState] = React.useState([{ value: 0 }]);
const prevState = usePrevious(state);
React.useEffect(() => {
if (prevState !== state) {
try {
console.log(
'pref',
prevState[0].value,
'current',
state[0].value
);
} catch (e) {
console.log('not set yet');
}
}
}, [prevState, state]);
// }, [state])
const _onClick = () => {
const tempState = [...state];
//you were mutating state here
tempState[0] = {
...tempState[0],
value: tempState[0].value + 1,
};
setState(tempState);
};
return (
<div>
<div>
prevStateValue:{' '}
{prevState ? prevState[0].value : 'undefined'}
</div>
<div>stateValue: {state[0].value}</div>
<button onClick={_onClick}>click</button>
</div>
);
}
ReactDOM.render(<App />, document.getElementById('root'));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.8.4/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.8.4/umd/react-dom.production.min.js"></script>
<div id="root"></div>
答案 1 :(得分:0)
您正在将state
的引用传递给ref
而不是值。在分配给ref.current之前先克隆对象会有所帮助。
function usePrevious(value) {
const ref = React.useRef();
React.useEffect(() => {
ref.current = JSON.parse(JSON.stringify(value));
});
return ref.current;
}