React.js 官网资料摘记:State & 生命周期

来源:互联网 发布:宁夏广电网络总经理 编辑:程序博客网 时间:2024/05/16 14:09

state & 生命周期

这个不是这一章的重点,但是下面的函数中有用到,所以先在这里提一下:

函数定义组件

比如下面这样形式的组件:

class Clock extends React.Component {    render(){        return (            <h1>{this.props.title}</h1>        );    }}

可以简写成下面这样的函数形式

function Clock(props){    return (        <h1>{props.title}</h1>    );}ReactDOM.render(    <Clocl title='函数定义组件' />,    document.getElementById("root"));

看上一篇中关于时钟组件的例子,这里我们不再外部设置定时任务,之后调用函数来重新渲染这样的方式,我们把上述全部功能封装进Clock组件中。

为一个类添加局部状态

class Clock extends React.Component{    constructor(props){        super(props);        this.state={            date:new Date()        };    }    render(){        return (            <div>                <h1>定时器显示:</h1>                <h2>{this.state.date.toLocaleTimeString()}</h2>            </div>        );    }}ReactDOM.render(    <Clocl />,    document.getElementById('root'));

还没有写完,上面只是把基本结构搭建出来了,并把实现显示从传入参数this.props.date.toLoaclTimeString()的方式变成了this.state.date.toLocaleTimeString(),该组件现在并不需要外部传递参数,组件本身就会显示时间,至于更新,看下面:

将生命周期方法添加到类中

这里先介绍两个函数:

  • componentDidMount
  • componentWillMount

关于这两个函数的简单介绍看这里,为了实现定时任务,我们设置在组件被渲染到DOM后的函数:componentDidMount中设置定时任务:

componentDidMount(){    this.timeID=setInterval(        ()=>this.tick(),        1000    );}

这里timeID只是个随便设置的参数,重点是我们要设置该组件内部的tick()函数每隔一秒运行一次。下面展示tick()函数:

tick(){    this.setState(        {date:new Date()}    );}

这里顺带再展示一下释放掉该定时任务:

componentWillMount(){    clearInterval(this.timeID);}

下面说一下上面代码的运行顺序:

  • constructor()运行,将组件私有属性state中的date设置成new Date(),这里可以说是初始化。
  • componentDidMount()运行,设置定时运行tick()函数
  • tick()函数中使用唯一能更新sate的函数setState更新state
  • 在输出中输出state中的date,就能把全部的时钟功能封装到一个组件内部了。
  • 最后在该组件被释放掉时,删除掉定时任务,不再占用系统资源

正确地使用状态

不要直接更新状态

下面对state直接赋值的方式是不会更新组件输出的:

this.state.date=new Date();

而是要使用函数setState

this.setState({date:new Date()})

状态更新可能是异步的

  • 当你多次调用setState()时,React会把多次调用构建成一次调用,所以当你设置了setState()可能不是立刻生效的
  • 并且由于this.propsthis.state不是同步更新的,所以你最好不要靠这两者的值决定下一步的代码。

要想state的值与prop的值同步更新,可以使用下面的形式:

形式1:

this.setState((state,props)=>({    PropsName:state.firstName+" "+props.lastName}));

形式2:

this.setState(function(state,props){    return {        PropsName:state.firstName+" "+props.lastName    };});

状态更新合并

当你在constructor中初始化state时可能设置了多个值:

constructor(props){    super(props);    this.state={        posts:[],        comments:[]    };}

当你下面单独更新其中一部分时:

this.setState({posts:'单独设置post的值'});this.setState({comments:"这里单独设置comments"});

 并不会影响另一个的设置,每个属性都是独立的!

数据自顶向下流动

比如我返回这么一个组件,这里用组件的简写形式:

function Clock(props){    return (        <h1>{props.date.toLocaleString()}</h1>    );}ReactDOM.render(    <Clock date={new Date} />,    document.getElementById("root"));

Clock中,他并不需要关心props.date的来源,只要知道该组件是父级组件传递进来的一个参数即可。