繁体   English   中英

Redux Reducer:不确定我是否将项目(新的或旧的)设置为正确状态

[英]Redux reducer: not sure if I am setting items (new or old) to state correctly

我正在为学校的期末项目创建一个网站。

到目前为止,我正在尝试渲染两个视图。 两者都从我的express / api端点返回集合。 一种行为正确,另一种则完全无聊。

我相信我的问题是我在reducer中创建新状态并知道一个哑组件何时可以访问道具的方式。 但是在此之前,这里是错误。

在不太闷闷的页面上:

invariant.js:42未捕获(已承诺)错误:setState(...):采用状态变量的对象进行更新或返回状态变量的对象的函数。

和,

警告:SingleCountry.state:必须设置为对象或为null

在第二页上:

未捕获(承诺)错误:setState(...):需要更新状态变量的对象或返回状态变量的对象的函数。

我也得到:

错误:发送标头后无法设置标头。

当我尝试从不太闷闷的首页导航到单个页面/视图时,就会发生这种情况。 那不应该发生,因为我相信我的路线已经被锁定。

这是来自路由/ api,我正在使用Express ...

router
  .route('/')
  .get((req, res, next) => {
    return Country.findAll({ include: [Aircraft] })
      .then(countries => {
        countries.filter(country => {
          return country.aircrafts.length > 0;
        });
      })
      .then(countries => res.json(countries))
      .catch(next);
  })
  .post((req, res, next) => {
    if (req.body) {
      Country.create(req.body)
        .then(country => {
          country.save();
          res.json(country);
        })
        .catch(next);
    }
  });

这是上述的减速器:

import { combineReducers } from 'redux';
import axios from 'axios';

const initialState = {
  topFiveCountries: [],
  oneCountry: {},
  countries: [],
};

// ACTION TYPES

const GET_TOP_COUNTRIES_BY_GFI = 'GET_TOP_COUNTRIES_BY_GFI';
const GET_COUNTRY = 'GET_COUNTRY';
const GET_COUNTRIES = 'GET_COUNTRIES';

// ACTION CREATORS
export function getTopFiveCountriesByGFI(topFiveCountries) {
  const action = {
    type: GET_TOP_COUNTRIES_BY_GFI,
    topFiveCountries,
  };
  return action;
}

export function getCountry(country) {
  const action = {
    type: GET_COUNTRY,
    country,
  };
  return action;
}

export function getCountries(countries) {
  const action = {
    type: GET_COUNTRIES,
    countries,
  };
  return action;
}

//THUNK CREATORS

export function fetchTopFiveCountriesByGFI() {
  return function thunk(dispatch) {
    return axios
      .get('/api/countries/top-five-countries')
      .then(res => res.data)
      .then(countries => {
        const action = getTopFiveCountriesByGFI(countries);
        dispatch(action);
      });
  };
}

export function fetchCountry(countryId) {
  return function thunk(dispatch) {
    return axios
      .get('/api/countries/' + `${countryId}`)
      .then(res => res.data)
      .then(country => {
        const action = getCountry(country);
        dispatch(action);
      });
  };
}
export function fetchCountries() {
  return function thunk(dispatch) {
    return axios
      .get('/api/countries')
      .then(res => res.data)
      .then(countries => {
        const action = getCountries(countries);
        dispatch(action);
      });
  };
}

// REDUCER
const rootReducer = function(state = initialState, action) {
  switch (action.type) {
    case GET_COUNTRIES:
      return action.countries;
    // return { ...state, countries: action.countries };
    // return (state.countries = state.countries.concat(action.countries));
    case GET_TOP_COUNTRIES_BY_GFI:
      // return action.topFiveCountries;
      return { ...state, topFiveCountries: action.topFiveCountries };
    case GET_COUNTRY:
      return action.country;
    // return { ...state, oneCountry: action.country };

    default:
      return state;
  }
};

export default rootReducer;

我要去做的有趣的事情彼此之间并不太相似。 它们都是愚蠢的组件:

首先是TopFiveCountriesByGy:

import React from 'react';
import { BrowserRouter as Router, Route, Link, Switch } from 'react-router-dom';

export default function TopFiveCountriesByGFI(props) {
  const topFiveCountries = props.topFiveCountries;

  const flagStyle = {
    height: '50px',
    width: '100px',
  };
  return (
    <div className="row">
      <div className="twelve columns">
        <h2> - Top Five Coutries By GFI -</h2>
        <table className="u-full-width">
          <thead>
            <tr>
              <th>Name</th>
              <th>GFI</th>
              <th>Flag </th>
            </tr>
          </thead>

          {topFiveCountries.map(function(country) {
            return (
              <tbody key={country.id}>
                <tr>
                  <td>
                    <Link className="country-page-link" to={`/countries/${country.id}`}>
                      {country.name}
                    </Link>
                  </td>
                  <td>{country.GFI}</td>
                  <td>
                    <img style={flagStyle} src={country.flagUrl} />
                  </td>
                </tr>
              </tbody>
            );
          })}
        </table>
      </div>
    </div>
  );
}

其次是“国家”观点:

import React from 'react';
import { BrowserRouter as Router, Route, Link, Switch } from 'react-router-dom';

export default function Countries(props) {
  console.log('props', props.countries);

  const countries = props.countries;
  const flagStyle = {
    height: '50px',
    width: '100px',
  };
  return (
    <div className="row">
      <div className="twelve columns">
        <h2> - Countries -</h2>
        <table className="u-full-width">
          <thead>
            <tr>
              <th>Name</th>
              <th>GFI</th>
              <th>Flag </th>
            </tr>
          </thead>

          {countries &&
            countries.map(function(country) {
              return (
                <tbody key={country.id}>
                  <tr>
                    <td>
                      <Link className="country-page-link" to={`/countries/${country.id}`}>
                        {country.name}
                      </Link>
                    </td>
                    <td>{country.GFI}</td>
                    <td>
                      <img style={flagStyle} src={country.flagUrl} />
                    </td>
                  </tr>
                </tbody>
              );
            })}

          {/*  {countries ? (
            countries.map(country => {
              return (
                <tbody key={country.id}>
                  <tr>
                    <td>
                      <Link className="country-page-link" to={`/countries/${country.id}`}>
                        {country.name}
                      </Link>
                    </td>
                    <td>{country.GFI}</td>
                    <td>
                      <img style={flagStyle} src={country.flagUrl} />
                    </td>
                  </tr>
                </tbody>
              );
            })
          ) : (
            <div>Sorry no content yet!</div>
          )}*/}
        </table>
      </div>
    </div>
  );
}

任何帮助将不胜感激!

在此处输入图片说明

更新正如Deryck指出的那样,我的一个端点没有返回任何东西,但是我仍然遇到此错误:

SingleCountry.state: must be set to an object or null

您在promise的then返回一个undefined值,该值尝试进入res.json(countries) ,然后失败/抛出。 它仍然以undefined返回页面,导致setState()问题,因为那里什么也没有。

因此,在此块内

return Country.findAll({ include: [Aircraft] })
  .then(countries => {
    countries.filter(country => {              // <<-------- add `return` before countries
      return country.aircrafts.length > 0;
    });
  })
  .then(countries => res.json(countries))

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM