Reactjs 避免从“重新渲染”;输入“;或;textarea";在react js中

Reactjs 避免从“重新渲染”;输入“;或;textarea";在react js中,reactjs,Reactjs,目前在react js中,当我想用“状态”绑定文本区域或输入时,每次用户输入一个字母时,我都需要设置onChange方法和setState() 我听说如果您设置了状态刷新并重新渲染此组件中的所有内容 有没有更有效的方法?在这种情况下,使用“shouldComponentUpdate”是不合适的,因为如果我不进行“state”更新,所有用户输入都将被卡住。好吧,这就是在React中实现受控输入元素的方式 但是,如果性能是您最关心的问题,您可以将输入元素隔离在一个单独的有状态组件中,从而只触发自身的

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

我听说如果您设置了状态刷新并重新渲染此组件中的所有内容


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

好吧,这就是在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} />
    );
  }
}
类应用程序扩展组件{
render(){
返回(
...
...
);
}
}
类MyInput扩展组件{
构造函数(){
超级();
this.state={value::};
}
更新=(e)=>{
this.setState({value:e.target.value});
}
render(){
返回(
);
}
}

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

class App extends Component {    
  render() {
    return (
      <div>
        ...
        <input defaultValue="" />
        ...
      </div>
    );
  }
}
类应用程序扩展组件{
render(){
返回(
...
...
);
}
}

不过,请注意,通常建议使用受控输入。

如@Chris所述,您应该创建另一个组件,以优化仅对指定组件的重新渲染

但是,在某些用例中,您需要更新父组件,或者使用输入中输入的值将操作分派到一个还原器

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

注意:
clearTimeout
用于在用户停止键入至少200ms后调用
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;
从“React”导入React;
类SearchInput扩展了React.Component{
建造师(道具){
超级(道具);
this.tabTimeoutId=[];
此.state={
value:this.props.value,
};
this.onChangeSearch=this.onChangeSearch.bind(this);
}
componentWillUpdate(){
//如果timoutId存在,则表示正在启动超时
如果(this.tabTimeoutId.length>1){
clearTimeout(this.tabTimeoutId[this.tabTimeoutId.length-2]);
}
}
onChangeSearch(事件){
const{value}=event.target;
这是我的国家({
价值
});
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(){
常数{
一旦改变,
分钟长,
搜索延迟,
…其他道具,
}=这是道具;
返回此.onChangeSearch(事件)}
/>
}
}
SearchInput.propTypes={
minSearchLength:React.PropTypes.number,
searchDelay:React.PropTypes.number,
};
SearchInput.defaultProps={
最小搜索长度:3,
搜索延迟:200,
};
导出默认搜索输入;

希望有帮助。

您需要在构造函数中绑定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>
    );
  }
}
类MyComponent扩展组件{
构造函数(){
超级();
this.state={value::};
this.onChange=this.onChange.bind(this)
}
onChange=(e)=>{
const formthis=this;
设{name,value}=e.target;
formthis.setState({
[名称]:值
});
}
render(){
返回(
);
}
}

对于这个问题,您不需要复杂的react解决方案,只需要一点关于何时更新状态的常识。实现这一点的最佳方法是在超时时间内封装
setState
调用

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

这将仅在最后一次击键500毫秒后设置react元素的状态,并将防止在用户键入时使用Reender敲打元素

我想知道是否有一种方法可以重载
update
,这样您就可以跟踪
.val().length
,并且只在当前长度和上一个长度之间的差异超过某个数字时才重新渲染/更改状态。(我不是react人,只是一个基本的js人,但react与我的兴趣相关)。@cowbert,不,这真的不可能。如果react负责控制输入,则更新每个键入的X字母的状态将永远无法工作,因为您将永远无法首先键入第一个字母。简单演示:
setTimeout
cleartimout
是这个答案中最重要的部分。剩下的是不必要的复杂化。这只会增加500毫秒的延迟,直到键入的文本实际显示在输入字段中。它确实可以避免不断的重新渲染,但是感知的性能会受到严重影响,体验也会被破坏。@Cookie Monster我不同意-每次调用都不会产生任何成本(创建超时除外)。您也没有阻止文本显示在输入字段中,因为输入没有绑定到任何内容。想解释一下你的推理吗?哦,我想我明白你现在想表达的意思,但这是错误的。也许我的例子不够清楚。更改处理程序没有绑定到react元素,而是绑定到输入。输入将立即更新-因为您没有对输入绑定
val={this.state.val}
。相反,您只需在更改时手动更新状态。(但这样做需要500毫秒的延迟。)