【问题标题】:Selector parameter changed but render does not get called选择器参数已更改,但未调用渲染
【发布时间】:2019-11-18 08:06:45
【问题描述】:
//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
              }
              />
            }
            />
          )
        }

问题:最初,error 的值为 false,fetching 为 true。稍后获取为假,错误为真(因为 API 调用失败)。即使选择参数的值发生了变化,为什么渲染没有发生?我在渲染中放了一个 console.log 来检查,但只执行了一次。

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

添加reducer代码

【问题讨论】:

  • 是所有代码吗?你把 DataTable 连接到 redux 了吗?
  • 是的,我进行了连接,但不确定是否值得将所有代码放在这里。我相信我在选择器方法或 mapStatToProps 周围遗漏了一些东西。
  • 显示你的 getError 选择器
  • 添加为代码的第一行。
  • 还添加了reducer

标签: javascript react-redux reselect


【解决方案1】:

你的代码没有被更新的独特方式是你的props没有改变

看这个测试:

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) =&gt; get(state, 'myData.error', false);

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

尝试将选择器更改为:

export const getError = (state) =&gt; state.error;

【讨论】:

  • 我的问题是它没有更新。它只是不会重新渲染,即使在减速器中我正在更改错误的值(我可以在 console.log 中看到)
  • 不错,但结果还是一样,我可以看到,在错误时,Redux 商店中的标志已更改,我也使用 getError 获得了正确的标志,但它仍然没有呈现。
  • @TechTurtle 用最小的可重现案例更新您的问题。没有全局视野,我帮不了你。顺便说一句,如果不更新你的道具不会被改变。
  • 如果我输入的代码更少,那么人们会要求显示更多的代码。一种情况是,即使我的输入参数(在这种情况下为“错误”)被更改,渲染部分也不会被调用。
【解决方案2】:

真正的罪魁祸首是shouldComponentUpdate,其中写入的条件不允许渲染。 我相信文件应该提到同样的 - 只是为了给出提示。

【讨论】:

    猜你喜欢
    • 2018-12-04
    • 2017-05-20
    • 2016-01-28
    • 1970-01-01
    • 1970-01-01
    • 2017-06-23
    • 1970-01-01
    • 2019-08-23
    • 1970-01-01
    相关资源
    最近更新 更多