React2 组件的内部状态

来源:互联网 发布:java web多用户量优化 编辑:程序博客网 时间:2024/06/15 05:01

在上文《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

原创粉丝点击