Sivaprakash D
Sivaprakash D

Reputation: 328

React JS infinite loop on redux sagas

i am working on React,Redux and Redux-sagas, am getting infinite loop on the appliaition, please help out to fix this issue.

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);

Action 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()]);
}

This API which used in the Sagas will get the list of movies. so i was to get the list of movies when Item.js components rendered. currently, it's seems infinite loop on the application

Upvotes: 0

Views: 1226

Answers (1)

Klymenko Kyrylo
Klymenko Kyrylo

Reputation: 671

You're putting same action from saga, which you are "watching" for.

Usually, you should have some action with typeGET_LIST_REQUEST for dispatching from your component, and then, put action with type GET_LIST_SUCCESS from saga to get it in reducer.

So, your Action JS should looks like:

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;

Your Reducer

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

export default Reducer;

Your Saga

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()]);
}

Upvotes: 7

Related Questions