【问题标题】:reducer.state.props is undefined in nested actions react/reduxreducer.state.props 在嵌套动作 react/redux 中未定义
【发布时间】:2018-04-14 17:03:36
【问题描述】:

下面是我的动作和减速器文件 - 在我的组件状态下,我只看到 this.props.mainData - 但其他 subdataOneData 等没有被加载到状态 - 直到减速器我看到正确的动作被调度而且我还看到了子调用的数据 - 但它们没有到达我的组件 - 我有 mapStatetoprops - 我正在做的地方

新问题:根据更新的代码 - 当我在 reducer 中打印出有效负载时 - 我看到带有 api 数据的 maindata 但 SubData [{}, {}, {}] ..?

更新代码: 从 '../constants/types' 导入 { GET_DATA_AND_SUBDATA };

export function getMainData() {
  return async function getMainData(dispatch) {
    const { data } = await getMainDataAPI();
    const subData = data.map((item) => {
      const endpoint = 'build with item.name';
      return Request.get(endpoint);
    });
     console.log('subddd' + subData);  prints -> **[object Promise],[object Promise],[object Promise]**
    dispatch({
      type: GET_DATA_AND_SUBDATA,
      payload: { data, subData }
    });
  };
}

async function getMainDataAPI() {
  const endpoint = 'url';
  return Request.get(endpoint);
}

【问题讨论】:

  • 您首先发送 GET_DATA。它将更新状态(mainData)并尝试在调度 GET_subdata0、1 等之前重新渲染组件。您需要在访问道具之前进行验证或更改调度顺序。
  • 在访问道具之前进行验证是什么意思-? @praveenweb

标签: redux react-redux redux-thunk reducers


【解决方案1】:

问题在于您调度操作的方式。

您没有同时为mainDatasubdataOneData 提供数据。

export function getData() {
    return async function getData(dispatch) {
        const { data } = await getDataAPI();

        // This will cause first re-render
        dispatch({ type: GET_DATA, payload: data }); 

        Object.keys(data).map((keyName, keyIndex) => {
            const endpoint = 'ENDPOINT';
            Request.get(endpoint).then((response) => {
                // This will cause second re-render
                dispatch({
                    type: GET_subdata + keyIndex,
                    payload: response.data });
                }); 

            return keyIndex;
        });
    };
}

首先渲染您的subdataOneData 尚不可用。

您甚至没有在 reducer 中指定默认值,因此它将是 undefined

你可以像这样改变你的动作 thunk

export function getData() {
    return async function getData(dispatch) {
        const { data } = await getDataAPI();

        const subDataResponse =  await Promise.all( 
            Object.keys(data).map( () => {
                const endpoint = 'ENDPOINT';
                return Request.get(endpoint)                    
            })
        )

        const subData = subDataResponse.map( response => response.data )

        dispatch({
            type: GET_DATA_AND_SUBDATA
            payload: { data, subData }
        });

    };
}

并相应地更改您的减速器,以便一次设置所有数据。

export default function myReducer(state = {}, action) {
    switch (action.type) {
        case GET_DATA_AND_SUBDATA:
        return {
            ...state,
            mainData: action.payload.data,
            subdataOneData: action.payload.subData[0],
            subdataTwoData: action.payload.subData[1]
        };        
        default:
            return state;
    }
}

注意:在 reducer 中设置初始状态也是一个好习惯。

const initialState = {
    mainData: // SET YOUR INITIAL DATA
    subdataOneData: // SET YOUR INITIAL DATA
    subdataTwoData: // SET YOUR INITIAL DATA
}

export default function myReducer(initialState, action) {

【讨论】:

  • 那么在这个设置下,假设对象大小为 3,const subData 将是一个 3 值数组吗? stackoverflow.com/users/7030457/ivan
  • 好的,现在让我试试 - 非常感谢您的帮助 - 我会尽快通知您。
  • 我只是更改了一点代码来检索所有子数据。您还必须使用 try / catch 正确处理错误以使其可靠,但这不是答案范围的一部分。
  • 我已经用最新的代码更新了我的答案 - 我在 subDAta 数组中看到了空对象?我在这里想念什么..? stackoverflow.com/users/7030457/ivan
  • 请使用 console.log 检查包含 subDataResponse 的内容
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-08-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-06-01
相关资源
最近更新 更多