Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

React js single function with multiple setstate

Button Component (Child)

export default class Button extends React.Component {
  render() {
    var handleToUpdate = this.props.handleToUpdate;
    return (
      <button onClick={() => handleToUpdate(this.id)}>
        {this.props.title}
      </button>
    );
  }
}

Index(Parent)
in return

<Button title={title1} handleToUpdate={handleToUpdate.bind(this)} />
<Button title={title2} handleToUpdate={handleToUpdate1.bind(this)} />
<Button title={title3} />
<Button title={title4} />

in render

const title1 = "test1"
const title2 = "test2"
const title3 = "test3"
const title4 = "test4"
var handleToUpdate = this.handleToUpdate;
var handleToUpdate1 = this.handleToUpdate1;

function

  handleToUpdate() {
  this.setState({})
  }

  handleToUpdate1() {
  this.setState({})
  }

var handleToUpdate = this.handleToUpdate.bind(this);
var handleToUpdate1 = this.handleToUpdate1.bind(this);

There is no issue in my code but my way of approaching to the function is not good practice I believe.

What I am doing here is I made button component(Child) and calling it four times in the parent(index). I created onClick props to call function and then set state.

Is there any alternative method that I can create one function with 4 setState and call the state according to the button id which is clicked.

To Make it more clear.

Button 1 clicked => call singlefunction => setstate1

Button 2 clicked => cal singlefunction => setstate 2 ...

like image 893
contact dummy Avatar asked Oct 11 '18 00:10

contact dummy


People also ask

Can we use multiple setState in React?

Because of all the work actually involved when the setState() function is called, React may batch multiple setState() calls into a single update to improve performance. Thanks to this batching process, this. state might be updated asynchronously which means you cannot always rely on the current this.

Can you call setState twice?

Best kept React secret: you can declare state changes separately from the component classes. Notice how we're passing a function to setState. React will call that function with state and props, and use the result for next state. It is safe to call setState with a function multiple times.

Can you use setState in a function?

Syntax: We can use setState() to change the state of the component directly as well as through an arrow function. Example 1: Updating single attribute. We set up our initial state value inside constructor function and create another function updateState() for updating the state.

Can setState be synchronized?

Setting State Is Asynchronous React sets its state asynchronously because doing otherwise can result in an expensive operation. Making it synchronous might leave the browser unresponsive. Asynchronous setState calls are batched to provide a better user experience and performance.


2 Answers

If you are passing the id to the Button component, here is an alternative approach.

const buttons = [
  { id: 1, title: "test1" },
  { id: 2, title: "test2" },
  { id: 3, title: "test3" },
];

class App extends React.Component {
  state = {
    clicked: "",
  };

  onUpdate = ( id ) => {
    this.setState( { clicked: id } );
  };

  render() {
    console.log( this.state );
    return (
      <div>
        {buttons.map( button => (
          <Button
            key={button.id}
            button={button}
            onUpdate={this.onUpdate}
          />
        ) )}
      </div>
    );
  }
}

const Button = ( props ) => {
  const { button, onUpdate } = props;
  const handleUpdate = () => onUpdate( button.id );
  return <button onClick={handleUpdate}>{button.title}</button>;
};

ReactDOM.render( <App />, document.getElementById( "root" ) );
<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="root"></div>
like image 178
devserkan Avatar answered Oct 16 '22 09:10

devserkan


I would do something like this:

render(){
    const titles = ['title1', 'title2', 'title3', 'title4'];

  return(
    {
     titles.map((title, i)=>(
     <Button title={title} key={i} 
             handleToUpdate={()=>this.handleToUpdate(i)} />
               ))
    }
} 

in your handleToUpdate function/method, you should then use the parameter i to determine what is done. You could also use a parameter like (e)=>this.handleToUpdate(e) and then name the button with the title and access the name via e.target as follows:

handleToUpdate(e){
   const {name} = e.target;
   this.setState({[name]: true});
}

You can replace true in set state to whatever you want, however using a boolean is best if you are doing an action with a single potential result, i.e. always setting state in the same way as you presented in your question.

To pass the function with an id directly in the case of different locations for your buttons do this:

<Button title={title1} handleToUpdate={()=>this.handleToUpdate(1)} />

where 1 is an index with any number to plugin, or any key to use in a switch statement.

In your Button component change the onClick to:

<button onClick={this.props.handleToUpdate}> {this.props.title} </button>

You are basically binding the parameter to the function directly as in the map function I have above.

With this solution, you can just do a switch statement like in Ashley Brown's answer.

like image 2
David Kamer Avatar answered Oct 16 '22 09:10

David Kamer