react onclick routing redirecting whithout click

Viewed 33

I want to change page when the div is clicked but when the page loads it automatically navigates to another page without clicking the div.

Why is the code navigating without clicking?

import React, { Component } from "react";
import { useNavigate } from "react-router-dom";

export function Homerouter(props) {
  const navigate = useNavigate()
  return(<Home navigate={navigate}></Home>)
}

export default class Home extends Component{
  state = {categor: [{categ:"cat1", img: "https://teelindy.com/wp-content/uploads/2019/03/default_image.png"}, {categ:"cat2", img: "./imgs/notfound.png"}, {categ:"cat3", img: "./imgs/notfound.png"}, {categ:"cat4", img: "./imgs/notfound.png"}, {categ:"cat5", img: "./imgs/notfound.png"}, {categ:"cat6", img: "./imgs/notfound.png"}]}

  linkto(name) {
    //doing something else
    this.props.navigate(name)
  }
    
  createelem() {
    return(
      <div className="cont text-center">
        <div className="row row-cols-2 row-cols-lg-5 g-2 g-lg-3">
          {this.state.categor.map((items, index) => {
            return (
              <div key={items.categ} className="col">
                <div onClick={this.linkto("a")} className="card">
                  <img src={(items.img)} className="card-img-top" alt="..." />
                  <div className="card-body">
                    <h5 className="card-title">{items.categ}</h5>
                  </div>
                </div>
              </div>
            );
          })}
        </div>
      </div>
    )
  }

  render() {
    return(
      <React.Fragment>
        {this.createelem()}
      </React.Fragment>
    )
  }
}
2 Answers

Cause you're invoking the function linkto immediately. Wrap this.linkto("a") as this:

onClick={() => this.linkto("a")}

Issue

You've a callback that is being immediately invoked when the component renders.

{this.state.categor.map((items) => {
  return (
    <div key={items.categ} className="col">
      <div
        onClick={this.linkto("a")} // <-- immediately called when rendered
        className="card"
      >
        ...
      </div>
    </div>
  );
})}

Solution

You can either pass an anonymous callback function:

<div
  onClick={() => this.linkto("a")}
  className="card"
>
  ...
</div>

Or convert linkto to a curried function:

linkto(name) {
  ...
  return e => {
    // do anything with the click event e if necessary
    this.props.navigate(name); // navigate
  };
}

...

<div
  onClick={this.linkto("a")}
  className="card"
>
  ...
</div>

Or if there isn't any additional logic necessary directly call navigate in an anonymous callback:

<div
  onClick={() => this.props.navigate("a")}
  className="card"
>
  ...
</div>
Related