1

I am not able to update state on click of each button, but state is updating on a second click. I have filter function that runs when I click on any button, but it is not updating state when I click on button. Instead it is updating when I click a second time.

import React, { Component } from "react";
    
class Filter extends Component {
  state = {
    data: [],
    year: "",
    land: "",
    launch: "",
    url: "https://api.spaceXdata.com/v3/launches?limit=100&",
    str: "",
  };
    
    
  filterfunction(type, value) {
    this.setState({ [type]: value });
        
    if (type == "launch_year") {
      let str = type + "=" + value + "&";
      this.setState({ url: this.state.url + str });
      console.log("yearrrrrrrrrrrrrrrrrrrr", this.state.url);
      fetch(this.state.url)
        .then((response) => response.json())
        .then((data) => this.setState({ data: data }));
    } else if (type == "launch_success") {
      let str = type + "=" + value + "&";
      this.setState({ url: this.state.url + str });
      console.log("launcccccccccccccccccccc", this.state.url);
      fetch(this.state.url)
        .then((response) => response.json())
        .then((data) => this.setState({ data: data }));
    } else if (type == "land_success") {
      let str = type + "=" + value + "&";
      this.setState({ url: this.state.url + str });
      console.log("landdddddddddddddddddddddddd", this.state.url);
      fetch(this.state.url)
        .then((response) => response.json())
        .then((data) => this.setState({ data: data }));
    }
  }
    
  render() {
   return (
     <React.Fragment>
       <div className="filter-section">
         <h4 className="filter-headin">Filters</h4>
         <div className="filter-year">
           <p>Launch Year</p>
           <div className="row filter-row">
             <div className="col filter-column">
               <button
                 onClick={() => this.filterfunction("launch_year", 2006)}
                 type="button"
                 name=""
                 id=""
                 className="btn btn-primary year-button"
               >
                 2006
               </button>
             </div>
             <div className="col filter-column">
               <button
                 onClick={() => this.filterfunction("launch_year", 2007)}
                 type="button"
                 name=""
                 id=""
                 className="btn btn-primary year-button"
               >
                2007
              </button>
             </div>
           </div>
           <div className="row filter-row">
             <div className="col filter-column">
             <button
               onClick={() => this.filterfunction("launch_year", 2008)}
                 type="button"
                 name=""
                 id=""
                 className="btn btn-primary year-button"
              >
                2008
              </button>
            </div>
            <div className="col filter-column">
              <button
                onClick={() => this.filterfunction("launch_year", 2009)}
                type="button"
                name=""
                id=""
                className="btn btn-primary year-button"
              >
                2009
              </button>
            </div>
          </div>
          <div className="row filter-row">
            <div className="col filter-column">
              <button
                onClick={() => this.filterfunction("launch_year", 2010)}
                type="button"
                name=""
                id=""
                className="btn btn-primary year-button"
              >
               2010
            </button>
          </div>
          <div className="col filter-column">
            <button
              onClick={() => this.filterfunction("launch_year", 2011)}
              type="button"
              name=""
              id=""
              className="btn btn-primary year-button"
            >
              2011
            </button>
          </div>
        </div>
        <div className="row filter-row">
          <div className="col filter-column">
            <button
              onClick={() => this.filterfunction("launch_year", 2012)}
              type="button"
              name=""
              id=""
              className="btn btn-primary year-button"
            >
              2012
            </button>
          </div>
          <div className="col filter-column">
            <button
              onClick={() => this.filterfunction("launch_year", 2013)}
              type="button"
              name=""
              id=""
              className="btn btn-primary year-button"
            >
              2013
            </button>
          </div>
        </div>
        <div className="row filter-row">
          <div className="col filter-column">
            <button
              onClick={() => this.filterfunction("launch_year", 2014)}
              type="button"
              name=""
              id=""
              className="btn btn-primary year-button"
            >
              2014
            </button>
          </div>
          <div className="col filter-column">
            <button
              onClick={() => this.filterfunction("launch_year", 2015)}
              type="button"
              name=""
              id=""
              className="btn btn-primary year-button"
            >
              2015
          </button>
          </div>
        </div>
        <div className="row filter-row">
          <div className="col filter-column">
            <button
              onClick={() => this.filterfunction("launch_year", 2016)}
              type="button"
              name=""
              id=""
              className="btn btn-primary year-button"
            >
              2016
            </button>
          </div>
          <div className="col filter-column">
            <button
              onClick={() => this.filterfunction("launch_year", 2017)}
              type="button"
              name=""
              id=""
              className="btn btn-primary year-button"
            >
              2017
            </button>
          </div>
        </div>
        <div className="row filter-row">
          <div className="col filter-column">
            <button
              onClick={() => this.filterfunction("launch_year", 2018)}
              type="button"
              name=""
              id=""
              className="btn btn-primary year-button"
            >
              2018
            </button>
          </div>
          <div className="col filter-column">
            <button
              onClick={() => this.filterfunction("launch_year", 2019)}
              type="button"
              name=""
              id=""
              className="btn btn-primary year-button"
            >
              2019
            </button>
          </div>
        </div>
        <div className="row filter-row">
          <div className="col filter-column">
            <button
              onClick={() => this.filterfunction("launch_year", 2020)}
              type="button"
              name=""
              id=""
              className="btn btn-primary year-button"
            >
              2020
            </button>
          </div>
        </div>
      </div>
      <div className="successful-launch">
        <p>Successful Launch</p>
        <div className="row filter-row">
          <div className="col filter-column">
            <button
              onClick={() => this.filterfunction("launch_success", true)}
              type="button"
              name=""
              id=""
              className="btn btn-primary year-button"
            >
              True
            </button>
          </div>
          <div className="col filter-column">
            <button
              onClick={() => this.filterfunction("launch_success", false)}
              type="button"
              name=""
              id=""
              className="btn btn-primary year-button"
            >
              False
            </button>
          </div>
        </div>
       </div>
       <div className="successful-launch">
         <p>Successful Land</p>
           <div className="row filter-row">
             <div className="col filter-column">
               <button
                 onClick={() => this.filterfunction("land_success", true)}
                 type="button"
                 name=""
                 id=""
                 className="btn btn-primary year-button"
               >
                 True
               </button>
             </div>
             <div className="col filter-column">
               <button
                 onClick={() => this.filterfunction("land_success", true)}
                 type="button"
                 name=""
                 id=""
                 className="btn btn-primary year-button"
               >
                 False
               </button>
             </div>
           </div>
         </div>
       </div>
       </React.Fragment>
     );
   }
 }
    
 export default Filter;
rmlockerd
  • 3,776
  • 2
  • 15
  • 25

2 Answers2

1

You should console like below, setState() is async , so the state changes won't be applied immediately. If you want to log out the new state,setState() takes in a function as the second argument and performs that function when the state is updated

  this.setState({ url: this.state.url + str }, () =>console.log(this.state.url));

In both cases you're passing "land_success", true, one should be false, here I guess 2nd one should be false

     <div className="col filter-column">
        <button
          onClick={() => this.filterfunction("land_success", true)}
          type="button"
          name=""
          id=""
          className="btn btn-primary year-button"
        >
          True
        </button>
      </div>
      <div className="col filter-column">
        <button
          onClick={() => this.filterfunction("land_success", true)}
          type="button"
          name=""
          id=""
          className="btn btn-primary year-button"
        >
          False
        </button>
      </div>
Saswata Pal
  • 414
  • 2
  • 10
  • This is also true but my query is that how to update state on click of button, here my state is updating affter 2 clicks. – kanika rajput Oct 05 '20 at 18:19
  • is it happening for all the buttons or the one which I mentioned? – Saswata Pal Oct 05 '20 at 18:27
  • Saswata Pal Yes this is happening, actually i want to make change the url each time when user clicks on button , so if i click 2016 button it should be: " https://api.spaceXdata.com/v3/launches?limit=100&launch_year=2016" and if i click 2017 then it should be "https://api.spaceXdata.com/v3/launches?limit=100&launch_year=2017" and if i click another button along with year then it should be like: "https://api.spaceXdata.com/v3/launches?limit=100&launch_year=2017&land_success=true" i am confused that how to achieve this. – kanika rajput Oct 06 '20 at 05:02
  • In that case take your url in another variable and pass that variable in your fetch call ,or if you still want to use this.state.url you should do that in callback function after updating, the way I mentioned in my answer to do console. – Saswata Pal Oct 06 '20 at 05:08
  • The question you asked if that issue was resolved accept the answer and give a upvote, thanks – Saswata Pal Oct 06 '20 at 05:10
-1

Filter's state is updating with each click(even with first click). I suggest installing something like React Developer tool extension for chrome/firefox to quickly inspect what's going on with your components.

I don't know if this was intentional but your code right now just concatenates url on each click. So, if I click year 2016 and then on year 2017. Your url becomes: https://api.spaceXdata.com/v3/launches?limit=100&launch_year=2016&launch_year=2017&

and obviously, returns no data.

aks7891
  • 22
  • 2
  • Yes this is happening, actually i want to make change the url each time when user clicks on button , so if i click 2016 button it should be: " https://api.spaceXdata.com/v3/launches?limit=100&launch_year=2016" and if i click 2017 then it should be "https://api.spaceXdata.com/v3/launches?limit=100&launch_year=2017" and if i click another button along with year then it should be like: "https://api.spaceXdata.com/v3/launches?limit=100&launch_year=2017&land_success=true" i am confused that how to achieve this. – kanika rajput Oct 06 '20 at 04:58