【问题标题】:React JS infinite loop on redux sagas在redux sagas上反应JS无限循环
【发布时间】:2019-07-23 13:21:10
【问题描述】:

我正在研究 React、Redux 和 Redux-sagas,我在应用程序上遇到无限循环,请帮助解决这个问题。

Item.js

import React from "react";
import ReactDOM from "react-dom";
import { Link } from "react-router-dom";
import { gateway as MoltinGateway } from "@moltin/sdk";
import getList from "./../Action/Action";
import { connect } from "react-redux";
//import data from "./data";

export class Item extends React.Component {
  constructor(props) {
    super(props);
    this.state = {};
    this.pickItem = this.pickItem.bind(this);
  }
  pickItem(pickedItem, id) {
    //this.props.getList();
    //pickedItem.push(id);
    //this.setState({ pickItem: pickedItem });
  }
  componentWillMount() {
    this.props.getList();
  }
  render() {
    const { pickedItem } = this.state;
    //const  data = this.props.getList()
    console.log(this.props);
    return (
      <div className="ItemPage">
        <header>
          <h1>Online shopping</h1>
          <h2>Visit | Pick | Pay</h2>
        </header>
        <div
          onClick={this.pickItem.bind(this, pickedItem, 2)}
          className="item-list"
        >
          <div className="logoWarapper">
            <img
              src="https://rukminim1.flixcart.com/image/660/792/jmdrr0w0/shirt/q/q/r/xxl-tblwtshirtful-sh4-tripr-original-imaf9ajwb3mfbhmh.jpeg?q=50"
              width="100"
              height="100"
              alt=""
            />
          </div>
          <div className="itemWarapper">
            <h3>Item Name</h3>
            <p>
              <span>&#8377;</span>
              <span>3000</span>
            </p>
          </div>
        </div>
        <div onClick={this.pickItem} className="item-list">
          <div className="logoWarapper">
            <img
              src="https://rukminim1.flixcart.com/image/660/792/jmdrr0w0/shirt/q/q/r/xxl-tblwtshirtful-sh4-tripr-original-imaf9ajwb3mfbhmh.jpeg?q=50"
              width="100"
              height="100"
              alt=""
            />
          </div>
          <div className="itemWarapper">
            <h3>Item Name</h3>
            <p>
              <span>&#8377;</span>
              <span>3000</span>
            </p>
          </div>
        </div>
        <Link to="/payment">
          <button className="button">Make Payment</button>
        </Link>
      </div>
    );
  }
}

const mapStateToProps = state => ({
  list: state.list
});

const mapDispatchToProps = {
  getList
};
export default connect(
  mapStateToProps,
  mapDispatchToProps
)(Item);

动作 JS

export const ADD_TODO = "GET_LIST";

export const getList = () => ({
  type: "GET_LIST"
});
export default getList;

Reducer JS

const Reducer = (state = [], action) => {
  switch (action.type) {
    case "GET_LIST":
      return [
        ...state,
        {
          list: action
        }
      ];
    default:
      return state;
  }
};

export default Reducer;

Sagas JS

import { put, takeLatest, all, call } from "redux-saga/effects";

function* fetchNews() {
  const json = yield fetch(
    "https://api.themoviedb.org/3/movie/550?api_key=258ca659445121cb5d52f31961635ba7"
  ).then(response => response.json());

  yield put({ type: "GET_LIST", json: json.articles });
}
function* actionWatcher() {
  yield takeLatest("GET_LIST", fetchNews);
}
export default function* rootSaga() {
  yield all([actionWatcher()]);
}

这个在 Sagas 中使用的 API 将获取电影列表。所以我要在渲染 Item.js 组件时获取电影列表。目前,应用程序似乎是无限循环

【问题讨论】:

    标签: reactjs redux redux-saga


    【解决方案1】:

    您正在“关注”saga 执行相同的操作。

    通常,您应该有一些类型为GET_LIST_REQUEST 的操作用于从您的组件调度,然后,将类型为GET_LIST_SUCCESS 的操作从saga 放入reducer。

    所以,您的 Action JS 应该如下所示:

    export const ADD_TODO_REQUEST = "GET_LIST_REQUEST";
    export const ADD_TODO_SUCCESS = "GET_LIST_SUCCESS";
    
    export const getList = () => ({
      type: "GET_LIST_REQUEST"
    });
    export default getList;
    

    你的减速器

    const Reducer = (state = [], action) => {
      switch (action.type) {
        case "GET_LIST_SUCCESS":
          return {
            ...state,
            list: action.json
            };
        default:
          return state;
      }
    };
    
    export default Reducer;
    

    你的传奇

    import { put, takeLatest, all, call } from "redux-saga/effects";
    
    function* fetchNews() {
      const json = yield fetch(
        "https://api.themoviedb.org/3/movie/550?api_key=258ca659445121cb5d52f31961635ba7"
      ).then(response => response.json());
    
      yield put({ type: "GET_LIST_SUCCESS", json: json.articles });
    }
    function* actionWatcher() {
      yield takeLatest("GET_LIST_REQUEST", fetchNews);
    }
    export default function* rootSaga() {
      yield all([actionWatcher()]);
    }
    

    【讨论】:

    • undefined 到底是什么?我只是尝试在 saga 中向 url 发出请求,似乎没有 articles 字段作为响应。
    • 如果我们也传递 json,state 在 Item.js 中接收为 undefined
    • 你的 redux 状态是什么样的?将console.log(state) 放在reducer 中的`return [ ... ]` 之前。因为看起来您正在将新对象放入数组中,同时尝试从状态数组中获取键 list
    • 另外,请再次检查我的答案中的 reducer,我更新了一下
    • @SivaprakashD:这个答案解释了为什么会出现无限循环以及如何修复它。 undefined 的问题可能是(我怀疑是)一个完全不同的错误。请一次询问一件事,支持/接受有用的答案,如果您需要针对不同错误的帮助,请发布新问题。
    猜你喜欢
    • 1970-01-01
    • 2021-11-11
    • 1970-01-01
    • 2017-04-19
    • 1970-01-01
    • 2020-12-09
    • 2023-03-31
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多