简体   繁体   English

反应子组件重新渲染而不改变状态

[英]React child component Re-renders without state change

Im passing some data from one component to another (parent to child). 我将一些数据从一个组件传递到另一个组件(父组件到子组件)。 The data is passed without any issue from the enter and button click event. 传递数据时,输入和按钮单击事件没有任何问题。 I have added some validations by considering some key events (whether numbers are entered). 通过考虑一些关键事件(是否输入了数字),我添加了一些验证。 When ever the particular function related to this validation is triggered the child component auto manically re-renders. 每当触发与该验证相关的特定功能时,子组件都会自动重新渲染。 I cannot figure out why. 我不知道为什么。 here is my code. 这是我的代码。 I have used flux architecture. 我使用了助焊剂架构。

the main Parent(where keyevent takes place) 主要父项(发生键事件的位置)

    const validatebox = (textStatus) => {

    if (textStatus.length > 100) {
      return {
              error: '*status is too long',
            };
    }  else if (textStatus === '') {
      return {
              error: '*status cannot be empty',
            };
    }  else {
      return true;
    }
}


class PaserBox extends React.Component{

      constructor(props) {
            super(props);
            this.state = {
              textStatus: '',
              tags:{},
              showResults: false
            };

      }

      parse = () => {

        let status = this.refs.textinput.getValue();

        if(validatebox(status).error) {
          this.setState({
            textStatus: validatebox(status).error
          });
          return;

        }
        else {

          Actions.SendDataToTag(status);
          this.setState({ showResults: true });
          console.log(status);


        }
          this.clearText();
      };

      clearText = () => {
        document.getElementById('language').value = '';
      };

      handleKey = (e) =>{
        if (e.key === 'Enter') {
            this.parse();
        } 
        else {
          var keycode = e.which;
          if ((e.shiftKey == false && (keycode == 46 || keycode == 8 || keycode == 37 || keycode == 39 || (keycode >= 48 && keycode <= 57)))) {
            this.setState({
                textStatus: 'cannot enter numbers'
            });
          }
          else {
            this.setState({
              textStatus: ''
            });
          }
        }
      };

      handleKeyDown = (e) => {
        if (e.keyCode == 8) {
          this.setState({
              textStatus: ''
          });
        }
      };

      render(){
        return(
          <div>
            <Paper className="row col-xs-12 col-sm-12 col-md-12" style={style} zDepth={1}>
              <div className="col-xs-12 col-sm-12 col-md-12 col-lg-12">
                <TextField
                  fullWidth={true}
                  style={textfieldstyle}
                  errorText={this.state.textStatus}
                  ref="textinput"
                  onKeyPress={this.handleKey}
                  onKeyDown={this.handleKeyDown}
                  hintText="Enter sentence ..."
                  className="col-xs-12 col-sm-12 col-md-12"
                  name="ta"
                  id="language"/>
              </div>
            <div className="col-xs-9 col-sm-9 col-md-9"/>
            <div className="col-xs-3 col-sm-3 col-md-3" style={style_button}>
              <RaisedButton  secondary={true} label="Parse" onTouchTap={this.parse}/>
            </div>
            <div className="col-xs-1 col-sm-1 col-md-1"/>
            </Paper>
            <label style={styles}>Please enter sentences with correct grammar</label>
            <br/>
            { this.state.showResults ?  <div className="row">
                                          <div className="col-md-10">
                                            <ParserTreeBox/>
                                          </div>
                                          <div className="col-md-2">
                                            <ParserTags/>
                                          </div>
                                        </div> : null }
          </div>
        );
      }

}

export default PaserBox;

the child component where the states change happens 状态发生变化的子组件

   class ParserTreeBox extends React.Component{

  constructor(props) {
    super(props);
      this.state = {
        data: [],
        taggedData:{}
      }

     this._onChange = this._onChange.bind (this);
  }

  componentWillMount(){
    Store.addChangeListener(this._onChange);
  }

  componentWillUnmount(){
    Store.removeChangeListener(this._onChange);
  }

  _onChange(){
     this.setState({taggedData:Store.getData()});
  }

   render(){
     return(
        <div>
          <div>
            <ParserTree data={this.state.taggedData} />
          </div>
        </div>
     );
   }

}

export default ParserTreeBox;

Here the render function get triggered even though the states are not changed by the child components.I debugged the flux files they are working properly. 即使子组件未更改状态,此处也会触发渲染功能。我调试了助焊剂文件,使其正常工作。 Any reason why im getting this issue 即时通讯收到这个问题的任何原因

`Here the render function get triggered even though the states are `即使状态为
not changed by the child components 子组件未更改

As far as I understand you have a setState function which triggers re render PaserBox and you don't want it to cause re render of ParserTreeBox which is child of PaserBox 据我了解,您有一个setState函数,该函数触发重新渲染PaserBox,并且您不希望它导致重新渲染ParserTreeBox(它是PaserBox的子级)

If so it is quite normal that ParserTreeBox re renders because render function of PaserBox includes ParserTreeBox component. 如果是这样,ParserTreeBox重新呈现是很正常的,因为PaserBox的呈现功能包括ParserTreeBox组件。

When it is in render function of PaserBox it just passes data. 当它处于PaserBox的渲染功能中时,它只是传递数据。 But you can still neglect ParserTreeBox component re rendering shouldComponentUpdate(nextProps, nextState)function on ParserTreeBox side. 但是您仍然可以忽略ParserTreeBox组件在ParserTreeBox一侧重新渲染shouldComponentUpdate(nextProps,nextState)函数。

shouldComponentUpdate(nextProps, nextState){
 return this.state.taggedData == nextState.taggedData ? false : true
}

now it will check this method after that rendering of this component will be decided. 现在,将在确定此组件的呈现之后将检查此方法。

Change Component to PureComponent : Component更改为PureComponent

class MyComponent extends React.Component {

    // ...


class MyComponent extends React.PureComponent {

    // ...

It implements shouldComponentUpdate() with both a shallow prop and state comparison. 它通过浅层propstate比较来实现shouldComponentUpdate()

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM