Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Pass a Variable Reference In React?

I am designing a react component, and am trying to reduce the codebase and remove code duplication.

One thing that has a lot of code duplication is the checking input in the setter variables. Much of these setters do the same checking before they actually set the variable. Now, I know I could abstract that checking to a function to reduce duplication. But I was wondering, is there anyway to take it a step further, and reduce it all down to a single function?

For Example:

setVariable1(e){
  // Input validation
  // Rewrite Variable1
}

setVariable2(e){
  // Input Validation
  // Rewrite Variable2
}

<input onChange={this.setVariable1} type="number" value={this.variable2} className="form-control" required/>

<input onChange={this.setVariable2} type="number" value={this.variable2} className="form-control" required/>

Now if I used an arrow function, or perhaps currying to pass the variable into the function. Would there be a way to pass the reference of the variable in, instead of the value? Sort of like how you can add the & in C to affect the address?

setVariableType1(e, var){
    // Input Validation
    // Set variable var
}

<input onChange={(e) => this.setVariableType1(this.variable1)} type="number"  value={this.variable2} className="form-control" required/>

<input onChange={(e) => this.setVariableType1(this.variable2} type="number"  value={this.variable2} className="form-control" required/>

However, I notice when I do it this way. Instead of passing the variable into the function, I just pass the variable's contents in. So is there a way to pass in the reference?

I am decently new to React and still learning the ins and outs, so maybe there is a completely different way to do this using the component hierarchy with props and states etc? I just can't seem to figure out the best way to do this, or even if it's proper to want to do this.

Any help would be appreciated, thanks!

like image 496
Kurt Anderson Avatar asked Sep 17 '25 17:09

Kurt Anderson


2 Answers

JavaScript is always pass by value (though for objects, their values are their references). What I'd do in this case is set state based on passed keys. So, something like this (assuming the use of class properties):

class Example extends React.Component {
  state = {
    email: '',
    password: '',
  }

  setInput = (key) => (event) => {
    this.setState({ [key]: event.target.value });
  }

  render() {
    return (
      <div>
        <input value={this.state.email} onChange={this.setInput('email')} />
        <input value={this.state.password} onChange={this.setInput('password')} />
      </div>
    );
  }
}

Here, setInput is a curried function. So, you can specify a certain key in state you want to change, then it returns a handler for that specific key using computed properties.

like image 145
Andrew Li Avatar answered Sep 20 '25 07:09

Andrew Li


Just a different approach with name attribute. Also, it uses setInput function with reference. With this method, it is not recreated in each render.

class App extends React.Component {
  state = {
    foo: "",
    bar: "",
  }

  setInput = e =>
    this.setState({
      [e.target.name]: e.target.value
      });

  render() {
    return (
      <div>
        Foo: <input name="foo" onChange={this.setInput} />
        <br />
        Bar: <input name="bar" onChange={this.setInput} />

        <p>Foo is: {this.state.foo}</p>
        <p>Bar is: {this.state.bar}</p>
      </div>
    );
  }
}

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 27
devserkan Avatar answered Sep 20 '25 07:09

devserkan