Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

Function sent as props being called continuously – React.js

I am making a newsapp i want it to have different categories, instead of using react-router-dom for navigation what i want to do is create a state object and create a key in it named category and set current category as it’s value and i have sent that key as a props to news component where i fetch news and embed that category to the fetch URL

I have made a function to set the category and its in app.js I have sent it to navbar component as props, the issue i am facing is that i can’t select a category, because for some reason the onClick of the very last category is being called continuously and I know this because I console logged the category in setCategory function, can anyone tell me why this is happening

code in app.js:

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

import './App.css';
import React, { Component } from 'react'
import Navbar from './components/Navbar';
import News from './components/News';

export default class App extends Component {
  constructor() {
    super()
    this.state = {
      darkMode: "light",
      country: "us",
      category: "general",
      key: "general"
    }
  }

  setCategory = (cat)=> {
    this.setState({
      category: cat
    })
    console.log(this.state.category)
  }

  setCountry = (cntry)=> {
    this.setState({
      category: cntry
    })
  }

  setDarkMode = () => {
    if (this.state.darkMode === "light") {
      this.setState({ darkMode: "dark" })
      document.body.style.backgroundColor = "black"
    } else {
      this.setState({ darkMode: "light" })
      document.body.style.backgroundColor = "white"
    }
  }

  render() {
    return (
      <div>
        <Navbar setCategory={this.setCategory} setCountry={this.setCountry} setDarkMode={this.setDarkMode} darkMode={this.state.darkMode} />
        <News key={this.state.category} category={this.state.category} country={this.state.country} pageSize={18} darkMode={this.state.darkMode} />
      </div>
    )
  }
}

code in Navbar component:

import React, { Component } from 'react'



export default class Navbar extends Component {
    constructor(props) {
        super(props)
        this.setCategory = this.props.setCategory
    }
    render() {
        return (
            <div>
                <nav className={`navbar navbar-expand-lg navbar-${this.props.darkMode} bg-${this.props.darkMode}`}>
                    <a className="navbar-brand" href="/">NewsMonkey</a>
                    <button className="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarSupportedContent" aria-controls="navbarSupportedContent" aria-expanded="false" aria-label="Toggle navigation">
                        <span className="navbar-toggler-icon"></span>
                    </button>

                    <div className="collapse navbar-collapse" id="navbarSupportedContent">
                        <ul className="navbar-nav mr-auto">
                            <li className="nav-item active">
                                <a className="nav-link" href="/">Home <span className="sr-only">(current)</span></a>
                            </li>
                            <li className="nav-item">
                                <a className="nav-link" href="/about">About</a>
                            </li>
                            <li className="nav-item dropdown">
                                <a className="nav-link dropdown-toggle" href="/" role="button" data-toggle="dropdown" aria-expanded="false">
                                    Categories
                                </a>
                                <div className="dropdown-menu">
                                    <p className="dropdown-item cursor-pointer" onClick={this.setCategory("business")}>Business</p>
                                    <p className="dropdown-item cursor-pointer" onClick={this.setCategory("science")}>Science</p>
                                    <p className="dropdown-item cursor-pointer" onClick={this.setCategory("technology")}>Technology</p>
                                    <p className="dropdown-item cursor-pointer" onClick={this.setCategory("entertainment")}>Entertainment</p>
                                    <p className="dropdown-item cursor-pointer" onClick={this.setCategory("health")}>Health</p>
                                    <p className="dropdown-item cursor-pointer" onClick={this.setCategory("sports")}>Sports</p>
                                    <div className="dropdown-divider"></div>
                                    <p className="dropdown-item cursor-pointer" onClick={this.setCategory("general")}>General</p>
                                </div>
                            </li>
                        </ul>
                        {/* <form className="form-inline my-2 my-lg-0">
                            <input className="form-control mr-sm-2" type="search" placeholder="Search" aria-label="Search" />
                            <button className="btn btn-outline-success my-2 my-sm-0" type="submit">Search</button>
                        </form> */}
                        <div className={`custom-control custom-switch text-${this.props.darkMode === "light" ? "dark" : "light"}`}>
                            <input type="checkbox" className="custom-control-input" onClick={this.props.setDarkMode} id="customSwitch1" />
                            <label className={`custom-control-label`} htmlFor="customSwitch1">Dark mode</label>
                        </div>
                    </div>
                </nav>
            </div>
        )
    }
}

>Solution :

This doesn’t do what you think it does:

onClick={this.setCategory("business")}

This calls the setCategory function immediately and uses the result of that function as the onClick handler. Don’t pass the result of calling a function to onClick, pass a function itself:

onClick={() => this.setCategory("business")}
Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading