xoomer
xoomer

Reputation: 321

ReactJS onClick setState to different element

I am new to react, and I am having a little issue. Maybe somebody can help me out.

So the issue is that I am unable to triger the element I want with onCLick function. Now I am trying to remove the navigation when

import React from "react";
import ReactDOM from "react-dom";

export default class Nav extends React.Component {
    constructor() {
        super();
        this.state = {navStatus: "navHide"};
    }

    navClose() {
        var navOpened = document.getElementById("myNav");
        navOpened.setState({navStatus: "navHide"});
    }

    navOpen() {
        this.setState({navStatus: "navShow"});
    }

    render() {
        return(
            <nav onClick={this.navOpen.bind(this)}>
                <div id="myNav" className={this.state.navStatus}>
                    <div className="navClose" onClick={this.navClose.bind(this)}>
                        <object className="navCloseBtn" type="image/svg+xml" data="svg/close.svg"></object>
                    </div>                  
                </div>
            </nav>
        );
    }
}

The error I am having is

nav.js:12 Uncaught TypeError: navOpened.setState is not a function

Also if you notice some patterns that I could improve in my code, I would really appreciate the feedback.

Thank You!

Upvotes: 9

Views: 59936

Answers (4)

Andres Paul
Andres Paul

Reputation: 1068

If you use a functional component you can use the set Functions

const [filters, setFilters] = useState({});

...

<Button onClick={() => setFilters([])}>Clear Filters</Button>

Upvotes: 0

1ven
1ven

Reputation: 7016

Only react components have setState method. Working example:

import React from "react";
import ReactDOM from "react-dom";

export default class Nav extends React.Component {
constructor() {
  super();

  this.state = {
    navStatus: "navHide"
  };

  this.navClose = this.navClose.bind(this);
  this.navOpen = this.navOpen.bind(this);
}

navClose(e) {
  e.stopPropagation();
  this.setState({
    navStatus: "navHide"
  });
}

navOpen() {
  this.setState({
    navStatus: "navShow"
  });
}

render() {
  return(
    <nav onClick={this.navOpen}>
      <div id="myNav" className={this.state.navStatus}>
        <div className="navClose" onClick={this.navClose}>
          <object
            className="navCloseBtn"
            type="image/svg+xml"
            data="svg/close.svg"
          ></object>
        </div>                  
      </div>
    </nav>
  );
}

Also you should bind event handlers in constructor instead of render method.

Upvotes: 8

YasirAzgar
YasirAzgar

Reputation: 1453

You can also use inline functions,

<nav onClick={() => this.setState(navStatus: "navShow")}>

but some argue that it has performance issue, https://medium.com/front-end-weekly/dont-use-inline-arrow-functions-as-properties-e3cae2680b9d

Upvotes: 2

Piyush.kapoor
Piyush.kapoor

Reputation: 6803

import React from "react";
import ReactDOM from "react-dom";

export default class Nav extends React.Component {
constructor() {
    super();
    this.state = {navStatus: "navHide"};
}

navClose() {
    var navOpened = document.getElementById("myNav");
    this.setState({navStatus: "navHide"});
}

navOpen() {
    this.setState({navStatus: "navShow"});
}

render() {
    return(
        <nav onClick={this.navOpen.bind(this)}>
            <div id="myNav" className={this.state.navStatus}>
                <div className="navClose" onClick={this.navClose.bind(this)}>
                    <object className="navCloseBtn" type="image/svg+xml" data="svg/close.svg"></object>
                </div>                  
            </div>
        </nav>
    );
}
}

Upvotes: 3

Related Questions