Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/ruby-on-rails/61.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 从Fetch操作返回undefined到Rails后端的状态_Javascript_Ruby On Rails_Reactjs_Redux_React Redux - Fatal编程技术网

Javascript 从Fetch操作返回undefined到Rails后端的状态

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

我已经设置了一个Rails后端(用于一组成分),它以前是工作的,但是现在我的Dispatch action Creator函数中的fetch操作返回一个
未定义的状态(不是检索成分)。
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;