React子组件重新呈现而不更改状态

时间:2016-11-19 18:02:53

标签: javascript reactjs flux

我将一些数据从一个组件传递到另一个组件(父对子)。输入和按钮单击事件传递的数据没有任何问题。我通过考虑一些关键事件(是否输入了数字)添加了一些验证。当触发与此验证相关的特定功能时,子组件自动重新呈现。我无法弄清楚为什么。这是我的代码。我使用了通量架构。

主要的父母(发生关键事件的地方)

    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;

状态发生变化的子组件

   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;

这里渲染函数会被触发,即使子组件没有改变状态。我调试了它们正常工作的磁通文件。我得到这个问题的任何原因

2 个答案:

答案 0 :(得分:1)

  

`这里即使状态为
,渲染函数也会被触发   没有被子组件改变

据我所知,你有一个setState函数触发重新渲染PaserBox,你不希望它导致重新渲染ParserTreeBox,这是PaserBox的孩子

如果是这样,ParserTreeBox重新渲染是很正常的,因为PaserBox的渲染函数包含ParserTreeBox组件。

当它在PaserBox的渲染功能中时,它只传递数据。但你仍然可以忽略ParserTreeBox组件在ParserTreeBox端重新渲染shouldComponentUpdate(nextProps,nextState)函数。

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

现在它将在确定此组件的渲染后检查此方法。

答案 1 :(得分:1)

Component更改为PureComponent

class MyComponent extends React.Component {

    // ...


class MyComponent extends React.PureComponent {

    // ...

它通过浅shouldComponentUpdate()prop比较来实现state