Passing an additional parameter with an onChange event

前端 未结 7 811
生来不讨喜
生来不讨喜 2021-01-31 07:33

What I\'m trying to do:

I am trying to pass a string from a child component to the handleChange function of a parent component.

What cur

相关标签:
7条回答
  • 2021-01-31 07:47

    In your handle event use double arrow function, there's no need to bind when using arrow function:

    handleChange = tags => (event) => {
        console.log(tags);
        console.log(event.target.value);
    }
    

    And in the Child:

    <fieldset onChange={this.props.handleChange("tags")}>
        <div>Tag 1: <input id="tag1" value={tags[0]} /></div>
        <div>Tag 2: <input id="tag2" value={tags[1]} /></div>
        <div>Tag 3: <input id="tag3" value={tags[2]} /></div>
    </fieldset>
    
    0 讨论(0)
  • 2021-01-31 07:47

    In order to pass a param from the child component to the parent you can take an argument to the arrow function.

    handleChange(event, section) {
        console.log(section);
        console.log(event.target.value);
    }
    <Child handleChange={(e, val) => this.handleChange(e, val)} />
    
    <fieldset onChange={(e) => this.props.handleChange(e, "tags")}>
        <div>Tag 1: <input id="tag1" value={tags[0]} /></div>
        <div>Tag 2: <input id="tag2" value={tags[1]} /></div>
        <div>Tag 3: <input id="tag3" value={tags[2]} /></div>
    </fieldset>
    

    Sample snippet

    class App extends React.Component {
      handleChange(e, val) {
        console.log(e.target.value, val);
      }
      render() {
        return(
          <Child handleChange={(e,val) => this.handleChange(e, val)}/>
        )
      }
    }
    
    class Child extends React.Component {
      
      render() {
        return(
          <input type="text" onChange={(e) => this.props.handleChange(e, 'tab')}/>
        )
      }
    }
    
    ReactDOM.render(<App/>, document.getElementById('app'));
    <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="app"></div>

    0 讨论(0)
  • 2021-01-31 07:51

    As the OP, I had originally posted this as a follow up on my question, but it was deleted and I was told to post it as an answer instead, so here it is:

    Based on Ritesh Bansal's answer, I have learned the following:

    The following line was not working because when using parenthesis after the function name, the function is called immediately rather than waiting for a change to happen:

    <fieldset onChange={this.props.handleChange("tags")}>
    

    The above will not work, neither would a function such as this:

    <fieldset onChange={this.props.handleChange()}>
    

    The above would also get called immediately on first render.

    There are two solutions to this:

    The not-so good way:

    <fieldset onChange={this.props.handleChange.bind(this, "tags")}>
    

    The much better way:

    <fieldset onChange={(evt) => this.props.handleChange("tags", evt)}>
    

    The problem is now solved. Thank you everyone!

    Update:

    I also researched Shubham Khatri's suggestion to change the child element to this:

    <Child handleChange={(e,val) => this.handleChange(e, val)}/>
    

    I did not realize that using bind in the render function, that every time render is called it creates a new function instance. I can, therefore, either use Shubham Khatri's method, or bind the methods in the constructor.

    0 讨论(0)
  • 2021-01-31 07:54

    No anonymous function defined on each render():

    Most of the answers here recommend an anonymous function defined in render(), which, as Davidicus pointed out, is not recommended: https://medium.freecodecamp.org/why-arrow-functions-and-bind-in-reacts-render-are-problematic-f1c08b060e36

    François's answer avoids that problem, but as Vael Victus pointed out, that requires transform-class-properties.

    However, what he's doing is just defining a function which defines a function, which you can otherwise do like this:

    constructor(props) {
      super(props);
      this.handleChange = (yourSpecialParam) => (event) => this.handleChange(yourSpecialParam).bind(this)
    }
    
    render() {
      return <button onClick={this.handleChange(1234)} >Click Me</button>
    }
    
    0 讨论(0)
  • 2021-01-31 08:06

    When you are writing this:

    <fieldset onChange={this.props.handleChange("tags")}>
    

    handleChange will be called immediately as soon as render is triggered.

    Instead, do it like this:

    <fieldset onChange={(e) => this.props.handleChange("tags", e)}>
    

    Now the handleChange will be called when onChange handler is called.

    0 讨论(0)
  • 2021-01-31 08:08

    You can do this:

    <fieldset onChange={(e) => this.props.handleChange("tags", e)}>
        <div>Tag 1: <input id="tag1" value={tags[0]} /></div>
        <div>Tag 2: <input id="tag2" value={tags[1]} /></div>
        <div>Tag 3: <input id="tag3" value={tags[2]} /></div>
    </fieldset>
    
    0 讨论(0)
提交回复
热议问题