React-Redux可用propType-值未定义

时间:2019-08-19 19:03:00

标签: react-redux

我正在尝试使用propTypes来帮助我检查和验证应用中的数据。数据很好,但是我得到警告; Warning: Failed prop type: The prop allSubjectSubcategories is marked as required in OddMainPage , but its value is未定义`。

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

组件

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;

1 个答案:

答案 0 :(得分:1)

您似乎在GET_ALL_SUBJECT_SUBCATEGORIES动作中将减速器的返回类型从数组更改为对象。

查看initialState中的getAllSubcategoriesReducer,您可以看到该值是一​​个数组。但是GET_ALL_SUBJECT_SUBCATEGORIES分支的返回值是一个对象。您需要在一个或另一个上进行标准化。

由于reducer的初始状态只是一个空数组,所以state.allSubjectSubcategoriesmapStateToProps的值就是那个空数组。因此,当您致电allSubjectSubcategories: state.allSubjectSubcategories.allSubjectSubcategories,时,您会得到undefined

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

// 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
})