【问题标题】:Setting state from react reducer returns proper value but doesn't cause re-render从反应减速器设置状态返回正确的值但不会导致重新渲染
【发布时间】:2021-10-11 18:39:28
【问题描述】:

我刚刚为我的排序算法可视化工具实现了化简器,并试图将我的数组状态设置为排序算法的结果。我 99% 确定我的 reducer 正在接收排序后的数组,然后返回它(因为我做了一些 console.logs),而且我也很确定变量本身确实发生了变化。

这是我的 reducer 和数组变量(*注意,函数中的值将是数组):

export const ACTIONS = {
    SET_VALUES: 'set-values'
}

function reducer(state, action) {
  switch (action.type) {
    case ACTIONS.SET_VALUES:
      console.log(action.payload.values)
      return action.payload.values
    default:
      return state
  }
}


const [values, dispatch] = useReducer(reducer, [])

这里是调用 dispatch 的排序算法:

  export function bubbleSort(array, dispatch) {
    var testArray = array
    console.log('sorting')
    var sorted = false
    while (!sorted) {
        var changed = false;
        for (var i = 0; i < testArray.length-1; i++) {
            if (testArray[i] > testArray[i+1]) {
                changed = true;
                var smaller = testArray[i]
                testArray[i] = testArray[i+1]
                testArray[i+1] = smaller
            }
        }
        if (!changed) {
            sorted = true
        }
    }
    dispatch({ type: ACTIONS.SET_VALUES, payload: { values: testArray}})
    console.log('sorted')
    console.log(array)   
} 

当打印传递给函数的原始数组(值)时,它是排序的。但是,屏幕上反映数组本身的条并没有改变,这让我相信没有发生重新渲染,并且条正在使用变量(值)的旧状态。有谁知道如何解决这个问题?

【问题讨论】:

    标签: javascript reactjs reducers


    【解决方案1】:

    你几乎做对了。问题是 React 使用引用相等 a===b 来检查是否有变化。因此,由于您对数组进行了适当的排序,因此引用没有改变,所以所有useReducer 钩子看到的是state===state,所以它没有重新渲染。

    我所做的只是在冒泡排序开始时创建一个新数组,这样它就不会发生变异。

    var testArray = array.slice();

    const { useReducer } = React;
    const ACTIONS = {
      SET_VALUES: "set-values",
    };
    
    function reducer(state, action) {
      switch (action.type) {
        case ACTIONS.SET_VALUES:
          console.log(action.payload.values);
          return action.payload.values;
        default:
          return state;
      }
    }
    
    function bubbleSort(array, dispatch) {
      var testArray = array.slice();
      console.log("sorting");
      var sorted = false;
      while (!sorted) {
        var changed = false;
        for (var i = 0; i < testArray.length - 1; i++) {
          if (testArray[i] > testArray[i + 1]) {
            changed = true;
            var smaller = testArray[i];
            testArray[i] = testArray[i + 1];
            testArray[i + 1] = smaller;
          }
        }
        if (!changed) {
          sorted = true;
        }
      }
      dispatch({ type: ACTIONS.SET_VALUES, payload: { values: testArray } });
      console.log("sorted");
      console.log(array);
    }
    
    const App = () => {
      const [values, dispatch] = useReducer(reducer, [5, 2, 3, 9, 10, 234, 432, 1]);
    
      return (
        <div>
          <button
            onClick={() => {
              bubbleSort(values, dispatch);
            }}
          >Sort</button>
          <div>{values.join(", ")}</div>
        </div>
      );
    };
    
    ReactDOM.render(<App/>, document.getElementById("root"));
    <script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.8.3/umd/react.production.min.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.8.3/umd/react-dom.production.min.js"></script>
    <div id="root"/>

    【讨论】:

      猜你喜欢
      • 2020-10-19
      • 2019-03-07
      • 1970-01-01
      • 2015-11-03
      • 1970-01-01
      • 2020-09-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多