React-redux:为什么在更新redux状态后呈现功能组件?

时间:2019-12-05 16:34:02

标签: reactjs redux

为什么在存储状态更改后分派用于更新react-redux状态的操作的组件重新渲染?重新渲染不应该仅在prop或组件状态更改时发生吗?

const BoxContainer=memo(({props})=>{


    const dispatch = useDispatch();

    //Setting action with dispatch with useCallBack hook for safe side

    const callAction =useCallback(
        (payload) => {
            dispatch(payload)
        },
        [],
    );
    const structure = useSelector(state => ({...state.FormState}));
    var form = generateForm(structure,callAction);

    return(   
        <React.Fragment>
                {form}
        </React.Fragment>

    );
});

减速器代码如下

export const FormState = (state = FormStructureState ,action) =>
{   
    switch(action.type){
        case 'UPDATE':
            return {
                ...state,
                Structure:action.Payload
            }
        case 'MOVEITEM':
              var sourceRow = action.sourceRow;
              var sourceCol = action.sourceCol;
              var destRow = action.destRow;
              var destCol = action.destCol;
              var destinationContent = state.Structure.row[destRow][destCol].content;
              state.Structure.row[destRow][destCol].content = state.Structure.row[sourceRow][sourceCol].content;
              state.Structure.row[sourceRow][sourceCol].content = destinationContent;
              return {...state}
        case 'SETTEMPLATE':
              var sourceRow = action.sourceRow;
              var sourceCol = action.sourceCol;
              state.Structure.row[sourceRow][sourceCol].content.template = action.template;
        default:
            return {...state}

    }


}

1 个答案:

答案 0 :(得分:1)

因为选择器无条件地每次 返回一个新对象:

useSelector(state => ({...state.FormState}));

useSelector will force a re-render if the return value is a new reference。不要那样做。

此外,请注意,您当前的减速器逻辑有很多问题。特别是,这些行正在改变现有状态:

state.Structure.row[destRow][destCol].content = state.Structure.row[sourceRow][sourceCol].content;

不要那样做。

还有一些样式问题:

  • 避免使用var
  • 使用解构语法提取变量,例如const {sourceRow, sourceCol} = action

我强烈建议您改用我们的official Redux Toolkit package,它将默认情况下捕获意外突变,并允许您编写更简单的reducer逻辑。