首页 > 解决方案 > React-Redux 陷入困境的 propType - 值未定义

问题描述

我正在尝试使用 propTypes 来帮助对我的应用程序中的数据进行类型检查/验证。数据正常,但我收到警告;Warning: Failed prop type: The propallSubjectSubcategories is marked as required inOddMainPage , but its value isundefined`。

我已经阅读了其他一些回复,但我还没有找到解决我的问题的解决方案。

零件

class OddMainPage extends React.Component {
    constructor(props) {
        super(props);

        this.state = {
            categoryTables: [],
            tableColumns: [],

            gettingColumns: false,
            selectedCategory: "",
            selectedTable: ""
        }
    }

    componentDidMount() {
        this.props.dispatch(getAllSubjectSubCategories());
    }

  //more code to render some data
}}

OddMainPage.propTypes = {
    allSubjectSubcategories: PropTypes.array.isRequired,
    subCategoryTables: PropTypes.array,
    tableColumns: PropTypes.array
}

const mapStateToProps = state => ({
    allSubjectSubcategories: state.allSubjectSubcategories.allSubjectSubcategories,
    subCategoryTables: state.subCategoryTables.subCategoryTables,
    tableColumns: state.tableColumns.tableColumns
})

export default connect(mapStateToProps)(OddMainPage);

减速器

const initialState = {
    subCategoryTables: [],
    allSubjectCategories: [],
    allSubjectSubcategories: []
}

export const getAllSubjectSubcategoriesReducer = (state = initialState.allSubjectSubcategories, action) => {
    switch (action.type) {
        case "GET_ALL_SUBJECT_SUBCATEGORIES":
            return {
                ...state,
                allSubjectSubcategories: action.allSubCats
            }
        default:
            return initialState.allSubjectSubcategories
    }
}

我也尝试将默认状态设置为default: return state但得到相同的结果。

店铺

import { createStore, applyMiddleware, compose } from "redux";
import thunk from "redux-thunk";
import rootReducer from "../reducers";

const initialState = {};
const middleware = [thunk];

let store;

if (window.navigator.userAgent.includes("Chrome")) {
  store = createStore(
    rootReducer,
    initialState,
    compose(
      applyMiddleware(...middleware),
      window.__REDUX_DEVTOOLS_EXTENSION__ &&
      window.__REDUX_DEVTOOLS_EXTENSION__()
    )
  );
} else {
  store = createStore(
    rootReducer,
    initialState,
    compose(applyMiddleware(...middleware))
  );
}

export default store;

标签: react-redux

解决方案


看起来您正在将减速器的返回类型从数组更改为GET_ALL_SUBJECT_SUBCATEGORIES操作上的对象。

查看initialStatefor getAllSubcategoriesReducer,您可以看到该值是一​​个数组。GET_ALL_SUBJECT_SUBCATEGORIES然而,分支的返回值是一个对象。您需要对其中一个进行标准化。

由于 reducer 的初始状态只是一个空数组,因此state.allSubjectSubcategoriesin的值mapStateToProps将是那个空数组。因此,当您调用时,allSubjectSubcategories: state.allSubjectSubcategories.allSubjectSubcategories,您会得到undefined.

如果要保留嵌套版本,则需要更改initialState(并修复 reducer 的默认情况):

// NOTE: I've nested all of your sub-reducer keys to match your `mapStateToProps`.
const initialState = {
    subCategoryTables: {
      subCategoryTables: [],
    },
    allSubjectCategories: {
      allSubjectCategories: [],
    },
    allSubjectSubcategories: {
      allSubjectSubcategories: [],
    }
}


export const getAllSubjectSubcategoriesReducer = (state = initialState.allSubjectSubcategories, action) => {
    switch (action.type) {
        case "GET_ALL_SUBJECT_SUBCATEGORIES":
            return {
                ...state,
                allSubjectSubcategories: action.allSubCats
            }
        // return `state` here or you will keep reseting your reducer state
        default:
            return state
    }
}

如果您想将减速器保持为像初始状态一样的数组,您将需要更新您的减速器和您的mapStateToProps

export const getAllSubjectSubcategoriesReducer = (state = initialState.allSubjectSubcategories, action) => {
    switch (action.type) {
        case "GET_ALL_SUBJECT_SUBCATEGORIES":
            // assuming action.allSubCats is an array, we want to replace this entire reducer state with the new array
            return action.allSubCats
        // return `state` here or you will keep reseting your reducer state
        default:
            return state
    }
}

现在上面的 reducer 总是返回一个数组,你可以更新你的mapStateToProps以删除之前引入的额外键:

const mapStateToProps = state => ({
    allSubjectSubcategories: state.allSubjectSubcategories,  // note the change here
    // you probably want these to be updated as well with similar changes to your other reducers
    subCategoryTables: state.subCategoryTables,
    tableColumns: state.tableColumns
})

推荐阅读