我正在尝试使用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;
答案 0 :(得分:1)
您似乎在GET_ALL_SUBJECT_SUBCATEGORIES
动作中将减速器的返回类型从数组更改为对象。
查看initialState
中的getAllSubcategoriesReducer
,您可以看到该值是一个数组。但是GET_ALL_SUBJECT_SUBCATEGORIES
分支的返回值是一个对象。您需要在一个或另一个上进行标准化。
由于reducer的初始状态只是一个空数组,所以state.allSubjectSubcategories
中mapStateToProps
的值就是那个空数组。因此,当您致电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
})