选择器参数已更改,但未调用渲染

时间:2019-07-08 19:08:44

标签: javascript react-redux reselect

//Reducer
const initialState = {
error: false,
fetching: false,
myData: []
}

export const getDataReducer = (state = initialState, action) => {

switch (action.type) {
    case ActionTypes.MyData.fetch.request:
        return { ...state,
              fetching: true,
              error: false,
              myData: initialState.myData
            }

    case ActionTypes.MyData.fetch.success:
        return {
            ...state,
            myData: action.payload
            fetching: false,
            error: false
        }

    case ActionTypes.MyData.fetch.error:

        return { 
              ...state,
              error: true,
              fetching: false
            }
        }

export const getError = (state) => get(state, 'myData.error', false);

        const mapStateToProps = (state) => {
          return getMyData(state);
        }

        export const getMyData = createSelector(
          [getClientId, getFetching, getError],
          (clientId, fetching, error) => {
            console.log("in selector:", fetching, error)
            const state = store.getState();
            const myData = getData(state);

            let hasErrorOrNoData = error ? error : myData.length === 0;

            hasErrorOrNoData = fetching ? false : hasErrorOrNoData;
            console.log("in selector hasErrorOrNoData:", hasErrorOrNoData)

            return {
              error,
              fetching,
              hasErrorOrNoData,
              myData
            }
          }
        )
        export const DataTable = ({
          error,
          fetching,
          hasErrorOrNoData,
          myData
        }) => {
          console.log("in component this gets called only once")
          return ( <
            componentX rows = {
              myData
            }
            fetching = {
              fetching
            }
            error = {
              hasErrorOrNoData
            }
            errorComponent = { < NoDataMessage
              isError = {
                error
              }
              />
            }
            />
          )
        }

问题:最初,错误的值为false,提取为true。以后的获取为false,错误为true(因为API调用失败)。即使选择参数的值已更改,为什么不进行渲染?我将console.log放在render中进行检查,但是只执行了一次。

仅供参考:获取和clientId中的更改确实会触发渲染,只是不会触发的错误。

添加减速器代码

2 个答案:

答案 0 :(得分:0)

不更新代码的唯一方式是您的道具没有更改

查看此测试:

https://codesandbox.io/embed/friendly-mcclintock-rhwt9?fontsize=14

转到:

function reducer(state = { test: { fixed: "fixed", error: false } }, action) {
  return { test: { fixed: "fixed", error: !state.test.error } };
}

,然后将error: !state.test.error更改为error: state.test.error,更新将停止。

编辑

在您的减速器中,我看到:

case ActionTypes.MyData.fetch.error:

        return { 
              ...state,
              error: true,
              fetching: false
            }
        }

getError选择器是

export const getError = (state) => get(state, 'myData.error', false);

但是在您的初始状态:myData是一个数组,因此myData.error将不存在。您的getError选择器将始终返回false。

尝试将选择器更改为:

export const getError = (state) => state.error;

答案 1 :(得分:0)

真正的罪魁祸首是shouldComponentUpdate,其中写入的条件不允许渲染。 我认为文档应该提及相同的内容-只是为了提示。