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

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的来源,只要知道该组件是父级组件传递进来的一个参数即可。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值