React: trigger onChange if input value is changing by state?

后端 未结 9 1841
我在风中等你
我在风中等你 2020-11-30 04:34

Edit: I don\'t want to call handleChange only if the button has been clicked. It has nothing to do with handleClick. I gave an example in the @shubhakhatri

相关标签:
9条回答
  • 2020-11-30 05:12

    you must do 4 following step :

    1. create event

      var event = new Event("change",{
          detail: {
              oldValue:yourValueVariable,
              newValue:!yourValueVariable
          },
          bubbles: true,
          cancelable: true
      });
      event.simulated = true;
      let tracker = this.yourComponentDomRef._valueTracker;
      if (tracker) {
          tracker.setValue(!yourValueVariable);
      }
      
    2. bind value to component dom

      this.yourComponentDomRef.value = !yourValueVariable;
      
    3. bind element onchange to react onChange function

       this.yourComponentDomRef.onchange = (e)=>this.props.onChange(e);
      
    4. dispatch event

      this.yourComponentDomRef.dispatchEvent(event);
      

    in above code yourComponentDomRef refer to master dom of your React component for example <div className="component-root-dom" ref={(dom)=>{this.yourComponentDomRef= dom}}>

    0 讨论(0)
  • 2020-11-30 05:12

    I had a similar need and end up using componentDidMount(), that one is called long after component class constructor (where you can initialize state from props - as an exmple using redux )

    Inside componentDidMount you can then invoke your handleChange method for some UI animation or perform any kind of component properties updates required.

    As an example I had an issue updating an input checkbox type programatically, that's why I end up using this code, as onChange handler was not firing at component load:

       componentDidMount() {
    
        // Update checked 
        const checkbox = document.querySelector('[type="checkbox"]');
    
        if (checkbox) 
          checkbox.checked = this.state.isChecked;
      }
    

    State was first updated in component class constructor and then utilized to update some input component behavior

    0 讨论(0)
  • 2020-11-30 05:18

    The other answers talked about direct binding in render hence I want to add few points regarding that.

    You are not recommended to bind the function directly in render or anywhere else in the component except in constructor. Because for every function binding a new function/object will be created in webpack bundle js file hence the bundle size will grow. Your component will re-render for many reasons like when you do setState, new props received, when you do this.forceUpdate() etc. So if you directly bind your function in render it will always create a new function. Instead do function binding always in constructor and call the reference wherever required. In this way it creates new function only once because constructor gets called only once per component.

    How you should do is something like below

    constructor(props){
      super(props);
      this.state = {
        value: 'random text'
      }
      this.handleChange = this.handleChange.bind(this);
    }
    
    handleChange (e) {
      console.log('handle change called');
      this.setState({value: e.target.value});
    }
    
    <input value={this.state.value} onChange={this.handleChange}/>
    

    You can also use arrow functions but arrow functions also does create new function every time the component re-renders in certain cases. You should know about when to use arrow function and when are not suppose to. For detailed explation about when to use arrow functions check the accepted answer here

    0 讨论(0)
提交回复
热议问题