Javascript 从Fetch操作返回undefined到Rails后端的状态
我已经设置了一个Rails后端(用于一组成分),它以前是工作的,但是现在我的Dispatch action Creator函数中的fetch操作返回一个Javascript 从Fetch操作返回undefined到Rails后端的状态,javascript,ruby-on-rails,reactjs,redux,react-redux,Javascript,Ruby On Rails,Reactjs,Redux,React Redux,我已经设置了一个Rails后端(用于一组成分),它以前是工作的,但是现在我的Dispatch action Creator函数中的fetch操作返回一个未定义的状态(不是检索成分)。 API端点工作得非常好(通过服务器检查),但是fetch操作并没有检索成分,而是返回一个未定义的response.json 我把断点放在各处,以检查状态。我也尝试更改组件的MapStateTrops的内容,但是在进入mapState功能之前,状态是undefined IngCreditList组件 import R
未定义的状态(不是检索成分)。
API端点工作得非常好(通过服务器检查),但是fetch操作并没有检索成分,而是返回一个未定义的response.json
我把断点放在各处,以检查状态。我也尝试更改组件的MapStateTrops
的内容,但是在进入mapState
功能之前,状态是undefined
IngCreditList组件
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);
还原剂
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;
这在IngredientList.js:42的structuredSelector
中
未捕获的TypeError:无法读取未定义的属性“成分”
我假设问题来自下面的reducer,您试图访问这里的action.json.contracents
属性:
switch (action.type) {
case "GET_INGREDIENTS_SUCCESS":
console.log(action.json);
return { ...state, ingredients: action.json.ingredients } // here
在以下代码段中,请检查响应值-变量json
-是如何传递给getingredientsaccess
函数的:
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'},
]
}
因此,要解决此问题,您可能需要更改减速器中的以下行:
switch (action.type) {
case "GET_INGREDIENTS_SUCCESS":
console.log(action.json);
// removed .ingredients
// original value: action.json.ingredients
return { ...state, ingredients: action.json }
我希望这能解决你的问题,如果不只是让我知道,我们可以进一步调查
此外,在渲染中调用components
变量上的map
函数之前,值得处理变量的null
和undefined
值,如下所示:
const { ingredients } = this.props;
const ingredientsList = ingredients != null ? ingredients.map(ingredient => {
return (
<li key={ingredient.id}>
{ingredient.id}. {ingredient.name}
</li>);
}) : null;
因此,我猜以下更正将在这里完成工作,并且很可能您不会进一步收到错误消息:
case "GET_INGREDIENTS_REQUEST":
console.log('Ingredients request received')
return state;
让我强调关于reducer的返回语句的一个重要事项:
在Redux中,reducer获取开始状态和要处理的项,并返回新状态
其他重要规则如下:
始终返回状态,即使您没有更改它,即使它只是null。您不能返回未定义的
因此,reducer应该在return语句中具有新的状态,在本例中,它是未定义的
,这导致了错误消息
请在此处进一步阅读有关reducer的内容:。您是否也可以添加一个关于配料reducer的代码段?我将action.json.contracents更改为action.json,但同样的问题也发生了:我从reducer的“get Components success”操作中获取json,这是reducer中的控制台日志:操作:{type:“GET_Components_SUCCESS”,json:{…}json:{Components:Array(891)}类型:“GET_Components_SUCCESS”\uuuuu proto_uuuu:Object action.json.Components:(891)[{…}等{…},]
但是,此信息出现在未捕获类型错误之后:无法读取IngCreditList组件中structuredSelector中未定义的
的属性“成分”。@Norbitrial刚刚用我的发现更新了答案,请检查上面的内容。很高兴提供帮助!:)
const { ingredients } = this.props;
const ingredientsList = ingredients != null ? ingredients.map(ingredient => {
return (
<li key={ingredient.id}>
{ingredient.id}. {ingredient.name}
</li>);
}) : null;
case "GET_INGREDIENTS_REQUEST":
console.log('Ingredients request received')
return // missing state
case "GET_INGREDIENTS_REQUEST":
console.log('Ingredients request received')
return state;