我已经设置了Rails后端(用于多种配料),并且以前可以运行,但是现在我的Dispatch Action Creator函数中的访存动作返回了undefined
状态(不检索配料)。
API端点运行得很好(通过服务器检查),但是提取操作未检索到成分,并且返回了未定义的response.json
。
我到处都放置断点以检查状态。我也尝试过更改组件的mapStateToProps
的内容,但是在进入undefined
函数之前,状态为mapState
。
IngredientList组件
import React from "react";
import PropTypes from "prop-types";
import { connect } from "react-redux";
import { createStructuredSelector } from "reselect";
import { getIngredients, hideIngredients } from "../actions";
class IngredientList extends React.Component {
render() {
const { ingredients } = this.props;
const ingredientsList = ingredients.map(ingredient => {
return (
<li key={ingredient.id}>
{ingredient.id}. {ingredient.name}
</li>
);
});
return (
<React.Fragment>
<div>
<button
className="button"
onClick={() => this.props.getIngredients()}
>
Get Ingredients
</button>
<button
className="button"
onClick={() => this.props.hideIngredients()}
>
Hide Ingredients
</button>
</div>
<ul>{ingredientsList}</ul>
</React.Fragment>
);
}
}
const structuredSelector = createStructuredSelector({
ingredients: state => state.ingredients
});
const mapDispatchToProps = { getIngredients, hideIngredients };
export default connect(
structuredSelector,
mapDispatchToProps
)(IngredientList);
动作
export function getIngredientsRequest() {
return {
type: GET_INGREDIENTS_REQUEST
};
}
export function getIngredientsSuccess(json) {
return {
type: GET_INGREDIENTS_SUCCESS,
json
};
}
export function hideIngredients() {
return dispatch => {
dispatch({ type: HIDE_INGREDIENTS });
};
}
export function getIngredients() {
return dispatch => {
dispatch(getIngredientsRequest());
return fetch(`v1/ingredients`)
.then(response => response.json())
.then(json => dispatch(getIngredientsSuccess(json)))
.catch(error => console.log(error));
};
}
减速器
const initialState = {
ingredients: []
};
function rootReducer(state = initialState, action) {
console.log(action.type);
switch (action.type) {
case "GET_INGREDIENTS_SUCCESS":
console.log(action.json);
return { ...state, ingredients: action.json.ingredients }
case "GET_INGREDIENTS_REQUEST":
console.log('Ingredients request received')
return
case "HIDE_INGREDIENTS":
console.log('Ingredients are being hidden')
return { ...state, ingredients: [] }
case "GET_INGREDIENT_REQUEST":
console.log('One Ingredient request received:', "id:", action.id)
return
case "GET_INGREDIENT_SUCCESS":
console.log('GET_INGREDIENT_SUCCESS')
const ingredients = action.json.ingredients;
const id = action.id;
return {
...state,
ingredients: ingredients.filter(ingredient => ingredient.id.toString() === id)
}
default:
return state
}
}
export default rootReducer;
GET_INGREDIENTS_REQUEST reducers.js:6
Ingredients request received reducers.js:12
这在structuredSelector
的{{1}}中
未捕获的TypeError:无法读取未定义的属性“成分”
答案 0 :(得分:0)
我认为问题出在以下您试图在此处访问action.json.ingredients
属性的减速器上:
switch (action.type) {
case "GET_INGREDIENTS_SUCCESS":
console.log(action.json);
return { ...state, ingredients: action.json.ingredients } // here
在以下代码段中,请检查如何将响应值-变量json
-传递给getIngredientsSuccess
函数:
export function getIngredients() {
return dispatch => {
dispatch(getIngredientsRequest());
return fetch(`v1/ingredients`)
.then(response => response.json())
.then(json => dispatch(getIngredientsSuccess(json))) // json value
.catch(error => console.log(error));
};
}
我的假设是,从API端点返回值的方式如下:
[
{id: 12, name: 'test12'},
{id: 13, name: 'test13'},
]
不是这样的:
{
ingredients: [
{id: 12, name: 'test12'},
{id: 13, name: 'test13'},
]
}
因此,要解决此问题,您可能需要在reducer中更改以下行:
switch (action.type) {
case "GET_INGREDIENTS_SUCCESS":
console.log(action.json);
// removed .ingredients
// original value: action.json.ingredients
return { ...state, ingredients: action.json }
我希望这能解决您的问题,即使不仅仅是让我知道,我们也可以进行进一步调查。
另外,在渲染之前,需要在变量null
上调用undefined
函数之前,为变量处理map
和ingredients
值,如下所示:
const { ingredients } = this.props;
const ingredientsList = ingredients != null ? ingredients.map(ingredient => {
return (
<li key={ingredient.id}>
{ingredient.id}. {ingredient.name}
</li>);
}) : null;
更新:
最初,您的代码调用getIngredientsRequest
函数,该函数转到以下代码行,其中代码不返回状态对象:
case "GET_INGREDIENTS_REQUEST":
console.log('Ingredients request received')
return // missing state
所以我想下面的更正将在这里完成工作,很可能您不会再收到错误消息:
case "GET_INGREDIENTS_REQUEST":
console.log('Ingredients request received')
return state;
让我重点介绍关于reducer的return语句的重要一件事:
在Redux中,reducer采用起始状态和要处理的项目,然后返回新状态。
其他重要规则如下:
即使您没有更改状态,即使它只是null,也总是返回状态。您可能不会返回undefined。
因此,减速器应该在return语句中具有新状态,在这种情况下,它是undefined
并导致错误消息。
请在此处进一步了解减速器:Actions and reducers: updating state。