componentstatus and 生命周期

1. componentstatus (State)

1.1 what is status?

status (State) is component in 部 可变data, 用于managementcomponent 动态behavior. 当status发生变化时, React会自动重 new 渲染component, updateUI.

status and Props 区别:

1.2 in classcomponentinusingstatus

in classcomponentin, status is a object, throughthis.state访问, throughthis.setState()methodmodify:

import React, { Component } from 'react';

class Counter extends Component {
  // 初始化status
  constructor(props) {
    super(props);
    this.state = {
      count: 0
    };
  }

  // 增加计数
  increment = () => {
    this.setState({ count: this.state.count + 1 });
  };

  // reducing计数
  decrement = () => {
    this.setState({ count: this.state.count - 1 });
  };

  render() {
    return (
      

计数器: {this.state.count}

); } } export default Counter;

1.3 in functioncomponentinusingstatus (Hooks)

in React 16.8之 after , 可以usinguseState Hook in functioncomponentinusingstatus:

import React, { useState } from 'react';

function Counter() {
  // 初始化status, useState返回status值 and updatefunction
  const [count, setCount] = useState(0);

  // 增加计数
  const increment = () => {
    setCount(count + 1);
  };

  // reducing计数
  const decrement = () => {
    setCount(count - 1);
  };

  return (
    

计数器: {count}

); } export default Counter;

2. State update规则

2.1 不要直接modifyState

直接modifyState不会触发重 new 渲染, 必须usingsetState()method:

// error - 直接modifyState
this.state.count = this.state.count + 1;

// 正确 - usingsetState()
this.setState({ count: this.state.count + 1 });

// functioncomponentinerror
count = count + 1;

// functioncomponentin正确
setCount(count + 1);

2.2 Stateupdate可能 is asynchronous

React可能会将 many 个setState()调用merge成一个调用, 以improvingperformance. 因此, 不能依赖当 before State值来计算 under 一个State:

// error - 可能不会按预期工作
this.setState({ count: this.state.count + 1 });
this.setState({ count: this.state.count + 1 }); // 只会增加1, 而不 is 2

// 正确 - usingfunction形式 setState
this.setState((prevState) => ({
  count: prevState.count + 1
}));
this.setState((prevState) => ({
  count: prevState.count + 1
})); // 会增加2

// functioncomponentin正确using
setCount(prevCount => prevCount + 1);
setCount(prevCount => prevCount + 1); // 会增加2

2.3 Statemerge

当usingsetState()updateState时, React会将 new Stateobject and 当 before Statemerge, 而不 is replace:

this.state = {
  name: '张三',
  age: 25
};

// 只updateage, name会保持不变
this.setState({ age: 26 });

3. component生命周期

3.1 what is 生命周期?

component生命周期 is 指component from creation to 销毁 整个过程, React in 不同阶段会调用specific method, 这些method称 for 生命周期method.

3.2 classcomponent 生命周期

classcomponent 生命周期可以分 for 三个阶段:

  1. 挂载阶段 (Mounting) : component被creation并插入DOM
  2. update阶段 (Updating) : component Props or State发生变化
  3. 卸载阶段 (Unmounting) : component from DOMin移除

3.3 常用生命周期method

阶段 method describes
挂载阶段 constructor() component初始化, 设置初始State
render() 渲染component, 返回JSX
componentDidMount() component挂载completion after 调用, 常用于data获取, DOMoperationetc.
UNSAFE_componentWillMount() 已废弃, 不推荐using
update阶段 render() 重 new 渲染component
componentDidUpdate(prevProps, prevState) componentupdatecompletion after 调用, 常用于DOMoperation, dataupdateetc.
shouldComponentUpdate(nextProps, nextState) 决定component is 否需要重 new 渲染, 返回boolean值
UNSAFE_componentWillUpdate() 已废弃, 不推荐using
UNSAFE_componentWillReceiveProps() 已废弃, 不推荐using
卸载阶段 componentWillUnmount() component卸载 before 调用, 常用于cleanresource, 取消subscribeetc.

3.4 生命周期example

import React, { Component } from 'react';

class LifecycleExample extends Component {
  constructor(props) {
    super(props);
    this.state = {
      count: 0
    };
    console.log('1. constructor - component初始化');
  }

  componentDidMount() {
    console.log('3. componentDidMount - component挂载completion');
    // 这里可以fordata获取, DOMoperationetc.
  }

  componentDidUpdate(prevProps, prevState) {
    console.log('4. componentDidUpdate - componentupdatecompletion');
    console.log(' before 一个status:', prevState);
    console.log('当 before status:', this.state);
  }

  componentWillUnmount() {
    console.log('5. componentWillUnmount - component即将卸载');
    // 这里可以cleanresource, 取消subscribeetc.
  }

  increment = () => {
    this.setState({ count: this.state.count + 1 });
  };

  render() {
    console.log('2. render - component渲染');
    return (
      

计数器: {this.state.count}

); } } export default LifecycleExample;

4. functioncomponent 生命周期 (Hooks)

4.1 useEffect Hook

in functioncomponentin, 可以usinguseEffect Hook来mockclasscomponent 生命周期method:

import React, { useState, useEffect } from 'react';

function LifecycleExample() {
  const [count, setCount] = useState(0);
  const [name, setName] = useState('React');

  // componentDidMount  and  componentDidUpdate  结合
  useEffect(() => {
    console.log('component挂载 or update');
    document.title = `计数: ${count}`;
  });

  // 仅 in 挂载时执行 (componentDidMount) 
  useEffect(() => {
    console.log('component挂载');
    // data获取, subscribeetc.
  }, []);

  // 仅 in count变化时执行
  useEffect(() => {
    console.log('count变化了:', count);
  }, [count]);

  // 仅 in count or name变化时执行
  useEffect(() => {
    console.log('count or name变化了:', count, name);
  }, [count, name]);

  // cleanfunction (componentWillUnmount) 
  useEffect(() => {
    const timer = setInterval(() => {
      console.log('定时器runin...');
    }, 1000);

    // cleanfunction
    return () => {
      console.log('component卸载 or 依赖变化, cleanresource');
      clearInterval(timer);
    };
  }, []);

  return (
    

计数器: {count}

setName(e.target.value)} placeholder="输入名称" />
); } export default LifecycleExample;

4.2 useEffect working principles

5. 练习

练习1: creation带status 计数器

creation一个带status 计数器component, package含增加, reducing and resetfunctions.

import React, { useState } from 'react';

function Counter() {
  const [count, setCount] = useState(0);

  const increment = () => {
    setCount(count + 1);
  };

  const decrement = () => {
    setCount(count - 1);
  };

  const reset = () => {
    setCount(0);
  };

  return (
    

计数器

{count}

); } export default Counter;

练习2: creation时钟component

creation一个时钟component, 实时显示当 before 时间, 每秒update一次.

import React, { useState, useEffect } from 'react';

function Clock() {
  const [time, setTime] = useState(new Date());

  useEffect(() => {
    // 设置定时器, 每秒update一次时间
    const timer = setInterval(() => {
      setTime(new Date());
    }, 1000);

    // cleanfunction, component卸载时清除定时器
    return () => {
      clearInterval(timer);
    };
  }, []);

  // format时间
  const formattedTime = time.toLocaleTimeString();

  return (
    

当 before 时间

{formattedTime}

); } export default Clock;