【问题标题】:Cannot get prevState value using userRef hook for array of objects无法使用对象数组的 userRef 挂钩获取 prevState 值
【发布时间】:2020-10-20 17:57:43
【问题描述】:

我正在尝试使用由 useRef 钩子制作的自定义钩子 usePrevious 比较新旧状态值,其中状态由对象数组组成。

在打印旧值和当前值时,它在两种情况下都会返回当前值,但是当它只是数字数组或者如果它是第一次渲染时,它工作得很好。

另外,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

【问题讨论】:

  • 您好像忘记了 usePrevious`useEffect 中的 deps 数组。它应该是[值]。请参阅usehooks.com/usePrevious 以供参考
  • @user0101 不,它没有用。

标签: javascript reactjs react-hooks


【解决方案1】:

你正在改变状态:tempState[0].value = state[0].value + 1;

这是一个有效的 sn-p:

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>

【讨论】:

    【解决方案2】:

    您将 state 的引用而不是值传递给 ref。在分配给 ref.current 之前克隆对象会有所帮助。

    function usePrevious(value) {
      const ref = React.useRef();
      React.useEffect(() => {
        ref.current = JSON.parse(JSON.stringify(value));
      });
      return ref.current;
    }
    

    【讨论】:

      猜你喜欢
      • 2021-02-19
      • 2021-10-09
      • 2021-02-06
      • 2021-11-25
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-08-14
      • 1970-01-01
      相关资源
      最近更新 更多