Flux
Flux

Reputation: 419

Is it possible to assign function references to state in react?

In my componenet, I have two buttons for which I want the onClick function to change depending on the component state.

Is it possible to assign function references to state variables?

For instance

 constructor() {
       this.foo = this.foo.bind(this);
       this.bar = this.bar.bind(this);
       this.state = {
         buttonMessage: "hello",
         buttonFunction: foo
       }
      }

    foo() {
      this.setState({
        buttonFunction: bar
      })
    }

    bar() {
      this.setState({
        buttonFunction: foo
      })
    }
   }

When I try the above code, I get an error saying that foo and bar are not defined. Perhaps this is just a syntax error? Would be nice to know if it is even possible to assign function references to the state variables.

Upvotes: 0

Views: 5727

Answers (3)

Rafiq
Rafiq

Reputation: 11475

For functional component:

 const [state, setState] = useState({
    viewToBarChange: "",
  });

<Tree
    setViewToBarChange={(callBack) => {
     setState({ ...state, viewToBarChange: callBack });
      }}
  >
</Tree>

Upvotes: 1

Flux
Flux

Reputation: 419

Simple answer concluded from discussion in comments to the original question: Yes, it is possible.

The problem I had in my example was that I forgot to use "this" when assigning the function reference in this.setState({buttonFunction: foo}), it should be this.setState({buttonFunction: this.foo}).

The following code will work:

 constructor() {
       this.foo = this.foo.bind(this);
       this.bar = this.bar.bind(this);
       this.state = {
         buttonMessage: "hello",
         buttonFunction: this.foo
       }
      }

    foo() {
      this.setState({
        buttonFunction: this.bar
      })
    }

    bar() {
      this.setState({
        buttonFunction: this.foo
      })
    }
   }

Big thanks to Yury Tarabanko for providing assistance.

Upvotes: 1

Patrick Ferreira
Patrick Ferreira

Reputation: 2053

Is this something like this you want?

// import React from 'react';

class HelloKitty extends React.Component {
  constructor(args) {
    super(args);
    this.foo = this.foo.bind(this);
    this.bar = this.bar.bind(this);

    this.state = {
      buttonMessage: "hello",
      buttonFunction: this.foo
    };
  }

  foo() {
    this.setState({
      buttonFunction: () => alert('foo'),
    })
  }

  bar() {
    this.setState({
      buttonFunction: () => alert('bar'),
    })
  }


  render() {
    return (
      <div className="root">
        <div>
          <span onClick={this.foo}>I'am foo</span>
          <span onClick={this.bar}>I'am bar</span>
        </div>

        <span onClick={this.state.buttonFunction}>{this.state.buttonMessage}</span>
      </div>
    );
  }
}

ReactDOM.render(
  <HelloKitty />,
  document.getElementById('container')
);
.root {
  display: flex;
  flex-direction: column;
  width: 50%;
}
  
.root div {
  display: flex;
  justify-content: space-between;
}

span {
  border: 1px solid black;
  margin: 30px;
  padding: .5em;
  width: 100px;
  cursor: pointer;
}
span:hover {
  background-color: #8f8;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>

<div id=container></div>

Upvotes: 3

Related Questions