React2 组件的内部状态

在上文《React1 创建React组件、组件的属性》 中,了解到组件的视图是属性的映射,通过改变组件属性可以触发组件重新渲染,从而改变组件的视图

其实组件的视图是由属性和内部状态映射而来的,即 view=f(props,state),跟属性类似,状态的改变也会触发组件的重新渲染,只不过状态是组件内部基于自身逻辑或者用户事件自己维护的,而不是由外部输入。


组件的内部状态

       可以通过 ReactDOM.render(<HelloMessage name="Tom" />,container) 的方式,将带有特定属性的组件渲染到页面的某个DOM节点中(container)

       示例:

        function Clock(props){
          return (
            <div>
               <h1>Hello World</h1>
               <h2>It Is {props.time}</h2>
            </div>
          )
        }
        function tick(){
          ReactDOM.render(
            <Clock time={new Date().toLocalTimeString()} />,
            document.getElementById('root')
          )
        }
        setInterval(tick,1000)
        示例解析:

                例子中定义了一个 Clock 组件,组件接收一个 time 属性,在组件外部通过 setInterval 周期性的调用 ReactDOM.render 不断更新 Clock 的属性并重新渲染

        在实际场景中,对于一个时钟组件,我们希望只调用一次 ReactDOM.render(<HelloMessage name="Tom" />,container) 然后它可以自己更新自己的视图

        更容易在页面上放置多个时钟,即复用性更好。

        要达到这个目的,就需要组件内部状态来支持。组件有一个特殊的属性 state 用来保存组件的内部状态。

        用户可以通过 this.setState(statePatch) 来更新组件的状态,组件的状态更新后会重新执行 render 方法来更新视图,以上例子内部改造后

        示例:

         class Clock extends React.Component{
           construstor(props){
             super(props);
               this.state={
                 time:new Date();
             }
           }
           componentDidMount(){
             this.timeID=setInterval(()=>this.tick(),1000);
           }
           componentWillUnmount(){
             clearInterval(this.timeID)
           }
           tick(){
             this.setState({
               time:new Date()
             })
           }
           render(){
             return(
               <div>
                  <h1>Hello World</h1>
                  <h2>It Is {this.state.time.toLocaleTimeString()}</h2>
               </div>
             )
           }
         }
         ReactDOM.render(
           <Clock/>,
           document.getElementById('root')
         )
          此时,Clock 作为一个完整的时钟组件就可以自己更新自己了,如果想要使用组件的内部状态,那组件必须以类继承的方式来定义,而不能使用函数式组件

         所以说,函数式组件也被常称作为无状态组件(stateless)

         例子中有用到 componentDidMount 和  componentWillUnmount 两个函数,它们是组件的生命周期函数

         改造后的例子,只需要调用一次 ReactDOM.render 即可,在实例的项目中,一个完整的单页面web应用,

         也只需要调用一次 ReactDOM.render 方法把根组件挂载到页面中即可

初始化组件内部状态

        在创建一个拥有内部状态的组件时,需要对内部状态进行初始化,即设置组件的最初状态是什么,

        是在构造函数 constructor 中设置 state 属性就可以

        示例:               

         class MyComponent extends React.Component{
           construstor(props){
             super(props);  //这行代码不可缺少
             this.state={
               name:'Luky'
             }
           }
         }
setState 大多数情况下是异步的

         setState 多数情况下是异步的,异步意味着通过 setState 更新组件状态后, 不能立刻通过 this.state 来获取到更新后的值

         另外当连续多次调用 setState 来更新同一个字段时,只有最后一次更新才会生效

         示例:            

        
         class Test extends React.Component{
           constructor(props){
             super(props);
             this.state={
               value:0
             }
           }
           addTree(){
             this.setState({value:this.state.value+1});
             this.setState({value:this.state.value+2});
             this.setState({value:this.state.value+3});
          }
           render(){
             return (
               <div>
                  <h1>Value:{this.state.value}</h1>
                  <button onClick={() => this.addTree()}>setState 3 times</button>
               </div>
             )
           }
         }
         ReactDOM.render(
           <Test />,
           document.getElementById('root')
         )

        示例结果:        

      只以最后一次更新为准

        如果需要代码正常工作,需要通过回调函数的方式来生成下一个state

        示例:

         this.setState(preState=>({value:preState.value+1}));
         this.setState(preState=>({value:preState.value+2}));
         this.setState(preState=>({value:preState.value+3}));

      示例结果:

     

        解析:

                 实际上只有在React能控制的事件处理过程中调用的 setState 才是异步的,如:生命周期函数,React内置的button、input等组件的事件处理函数

                 在某些特殊的组件中,可能需要通过addEventListener来设置某些DOM事件处理函数,在这种通过原生JS API 来设置的事件处理过程中调用setState就是同步的,

                 会立即更新 this.state,另外还有 setInterval、setTimeout等原生API的回调函数也是如此



文件借鉴于: http://react-china.org/t/react-react/15548

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值