避免在反应js

时间:2017-10-25 21:39:20

标签: reactjs

目前在react js中,当我想要将文本区域或输入与“状态”绑定时,我需要在每个用户输入单个字母时设置onChange方法和setState()

我听说如果setState反应js刷新并重新渲染此组件中的所有内容

有没有更有效的方法呢?在这种情况下使用“shouldComponentUpdate”是不合适的,因为如果我不进行“状态”更新,所有用户输入都将被卡住..

4 个答案:

答案 0 :(得分:4)

嗯,那就是你如何在React中实现受控输入元素。

但是,如果性能是您的主要关注点,您可以将输入元素隔离在单独的有状态组件中,因此只会触发自身重新渲染而不是整个应用程序。

类似于:

class App extends Component {    
  render() {
    return (
      <div>
        ...
        <MyInput />
        ...
      </div>
    );
  }
}


class MyInput extends Component {
  constructor() {
    super();
    this.state = {value: ""};
  }

  update = (e) => {
    this.setState({value: e.target.value});
  }

  render() {
    return (
      <input onChange={this.update} value={this.state.value} />
    );
  }
}

或者,您可以使用不受控制的输入元素。例如:

class App extends Component {    
  render() {
    return (
      <div>
        ...
        <input defaultValue="" />
        ...
      </div>
    );
  }
}

虽然注意通常建议使用受控输入。

答案 1 :(得分:3)

正如@Chris所说,你应该创建另一个组件来优化重新渲染到只有指定的组件。

但是,有些用例需要更新父组件或使用输入中输入的值向一个reducer发送一个操作。

例如,我创建了一个SearchInput组件,该组件为输入中输入的每个字符更新自身,但如果至少有3个字符,则仅调用onChange函数

注意:当用户停止输入至少200毫秒时,clearTimeout对于调用onChange函数 非常有用。

import React from 'react';

class SearchInput extends React.Component {
  constructor(props) {
    super(props);
    this.tabTimeoutId = [];
    this.state = {
      value: this.props.value,
    };

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

  componentWillUpdate() {
    // If the timoutId exists, it means a timeout is being launch
    if (this.tabTimeoutId.length > 1) {
      clearTimeout(this.tabTimeoutId[this.tabTimeoutId.length - 2]);
    }
  }

  onChangeSearch(event) {
    const { value } = event.target;

    this.setState({
      value,
    });

    const timeoutId = setTimeout(() => {
      value.length >= this.props.minSearchLength ? this.props.onChange(value) : this.props.resetSearch();
      this.tabTimeoutId = [];
    }, this.props.searchDelay);

    this.tabTimeoutId.push(timeoutId);
  }

  render() {
    const {
      onChange,
      minSearchLength,
      searchDelay,
      ...otherProps,
    } = this.props;

    return <input
      {...otherProps}
      value={this.state.value}
      onChange={event => this.onChangeSearch(event)}
    />
  }
}

SearchInput.propTypes = {
  minSearchLength: React.PropTypes.number,
  searchDelay: React.PropTypes.number,
};
SearchInput.defaultProps = {
  minSearchLength: 3,
  searchDelay: 200,
};

export default SearchInput;

希望它有所帮助。

答案 2 :(得分:0)

您需要在构造函数内部绑定onChange()事件函数,例如代码片段:

class MyComponent extends Component {
  constructor() {
    super();
    this.state = {value: ""};
    this.onChange = this.onChange.bind(this)
  }

  onChange= (e)=>{
    const formthis = this;
    let {name, value} = e.target;

    formthis.setState({
      [name]: value
    });
  }

  render() {
    return (
      <div>
        <form>
            <input type="text" name="name" onChange={this.onChange}  />
            <input type="text" name="email" onChange={this.onChange}  />
            <input type="text" name="phone" onChange={this.onChange}  />
            <input type="submit" name="submit" value="Submit"  />
        </form>
      </div>
    );
  }
}

答案 3 :(得分:-1)

对于此问题,您不需要复杂的反应解决方案,仅需要有关何时更新状态的一些常识。实现此目的的最佳方法是将setState调用封装在一个超时时间内。

class Element extends React.Component {
    onChange = (e) => {
        clearTimeout(this.setStateTimeout)
        this.setStateTimeout = setTimeout(()=> {
            this.setState({inputValue: e.target.value})
        }, 500)
    }
}

这只会在最后一次按键后500毫秒内在react元素上设置状态,并防止在用户键入内容时用重新渲染锤打该元素。