为什么有时会在设定后立即调用渲染,有时不会呈现



这是我的代码:

class TestState extends Component{
    constructor(props){
        super(props);
        this.state={
            text:"123"
        }
        this._hello = this._hello.bind(this)
    }
    _hello(){
        console.log("guangy will set state...");
        let num = Math.floor(Math.random()*100);
        this.setState({text: ""+num });
        console.log("guangy after set state...");
    }
    componentWillUpdate(){
        console.log("guangy componentWillUpdate")
    }
    render(){
        console.log("guangy render.....")
        return(<View>
            <Text>{this.state.text}</Text>
            <Button title="click" onPress={
                ()=>{
                    this._hello();
                }
            }/>
            <Button title="click1" onPress={
                ()=>{
                    setTimeout(()=>{
                        this._hello();
                    }, 10);
                }
            }/>
        </View>);
    }
}

当我单击第一个按钮时,日志为:

guangy will set state...
guangy after set state...
guangy componentWillUpdate
guangy render.....

单击第二个按钮时登录:

guangy will set state...
guangy componentWillUpdate
guangy render.....
guangy after set state...

我认为渲染函数应称为异步,实际上在大多数情况下,就像我单击第一个按钮时一样,但是当我单击第二个按钮时,渲染函数似乎称为同步,因为"之后"设置状态"日志是在"渲染"日志之后打印的。为什么会发生?

根据文档

将setState()视为请求,而不是立即命令 更新组件。为了更好地感知性能,React可能 延迟它,然后在单个通过中更新几个组件。反应 不能保证立即应用国家更改。 SetState()并不总是立即更新组件。它可能 批量或将更新推迟到以后。这使得读 在调用setState()为潜在的陷阱之后。

因此,人们会认为setState是异步的。但是,如果我们看一些关键词,例如:

React May 延迟

setState()不始终立即更新组件。

it May 批次或将更新推迟到以后。

所以我们认为setState可能是异步操作吗?
好吧,是的。

这是从源代码中获取的setState

ReactComponent.prototype.setState = function(partialState, callback) {
  invariant(
    typeof partialState === 'object' ||
    typeof partialState === 'function' ||
    partialState == null,
    'setState(...): takes an object of state variables to update or a ' +
    'function which returns an object of state variables.'
  );
  this.updater.enqueueSetState(this, partialState);
  if (callback) {
    this.updater.enqueueCallback(this, callback, 'setState');
  }
};

看起来像是普通的同步函数,实际上是setState,因为它自我不是异步,但执行的效果可能是。

我已经对自己进行了一些测试,我意识到React只会异步更新状态是React可以控制整个流动,而React无法控制流动,这意味着执行上下文不在然后,React将立即更新状态。

那么,什么可以采取React的控制?
诸如setTimeoutsetInterval AJAX请求和其他WebAPI之类的东西。
即使是附加在外部反应的事件处理程序也会触发这种行为。

实际上,这是满足我们实验的一小部分。
我有一个react组件App,其具有带有myValue密钥的状态和名为onClick的方法。
此方法记录当前状态,然后调用setstate然后再次记录状态。

App呈现3个元素:

  • myValue的当前值。
  • 我们通过React API附加onClick的按钮。
  • 我们通过addEventListener API附加onClick的按钮(反应的一面,请注意)。

当我们在React控制流程时单击第一个按钮时,状态会异步更新。

当我们单击第二个按钮时,React将立即更新状态。

class App extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      myVal: 0
    }
  }
  componentDidMount() {
    const el = document.getElementById('btn');
    el.addEventListener('click', this.onClick);
  }
  onClick = () => {
    console.log('Pre setState', this.state.myVal);
    this.setState({ myVal: this.state.myVal + 1 });
    console.log('Post setState', this.state.myVal);
    console.log('-------------------');
  }
  render() {
    const { myVal } = this.state;
    return (
      <div>
        <div>{myVal}</div>
        <button onClick={this.onClick}>Managed by react</button>
        <button id='btn'>Not Managed by react</button>
      </div>);
  }
}
ReactDOM.render(<App />, document.getElementById('root'));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>
<div id="root"></div>

相关内容

  • 没有找到相关文章

最新更新