Reputation: 419
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
Reputation: 11475
For functional component:
const [state, setState] = useState({
viewToBarChange: "",
});
<Tree
setViewToBarChange={(callBack) => {
setState({ ...state, viewToBarChange: callBack });
}}
>
</Tree>
Upvotes: 1
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
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