[React] 类组件/class组件

105 阅读2分钟

类组件的基本结构

class Welcome extends React.Component { 
  constructor(props) {
    super(props);
    this.state = {
      n: 0
    };
  }
  
  render() { 
    return (
      <h1>Hello, {this.props.name}</h1> 
    )
  }
}

props和state

props是外部属性,state是内部属性

props只读不写,state能读能写,但是不能直接修改state

class App extends React.Component {
  render() {
    return (
      <div className="App">
        <App2 messageForApp2="Hello" />
      </div>
    );
  }
}

class App2 extends React.Component {
  constructor() {
    super();
    this.state = {
      n: 0
    };
  }
  render() {
    return (
      <div className="App2">
        {this.props.messageForApp2}
        {this.state.n}
      </div>
    );
  }
}

state的读写

state需要在constructor()中初始化,并通过setState进行修改

[scode type="yellow" size=""]

注意:

  1. this.state.n += 1同样可以运行,但是背离了React的函数式编程思想,因此强烈不推荐在React中通过直接修改的方式改变数据
  2. setState是异步更新数据,因此下面代码中add()中log出的n是还未更新的值,因此推荐使用函数的方式更新,可以获得最新值,如add2()所示

[/scode]

class App extends React.Component {
  constructor() {
    super();
    this.state = {
      n: 0
    };
  }
  add() {
    this.setState({ n: this.state.n + 1 });
    console.log(this.state.n)
  }
  add2() {
    this.setState(state => { 
      const n = state.n + 1
      return {n} 
    }
  }
  render() {
    return (
      <div className="App">
        n: {this.state.n}
        <button onClick={() => this.add()}>+1</button>
      </div>
    );
  }
}

复杂state

类组件中的setState会自动合并第一层属性,但不会合并第二层属性,因此常使用...操作符

class App extends React.Component {
  constructor() {
    super();
    this.state = {
      n: 0,
      m: 0,
      user: {
        name: "A",
        age: 18
      }
    };
  }
  addN() {
    this.setState({ n: this.state.n + 1 });
    // m 不会被覆盖为 undefined
  }
  addM() {
    this.setState({ m: this.state.m + 1 });
    // n 不会被覆盖为 undefined
  }
  changeUser() {
    this.setState({
      // m 和 n 不会被置空
      user: {
        ...this.state.user
        name: "jack"
      }
    });
  }
  render() {
    return (
      <div className="App">
        n: {this.state.n}
        <button onClick={() => this.addN()}>n+1</button>
        m: {this.state.m}
        <button onClick={() => this.addM()}>m+1</button>
        <hr />
        <div>user.name: {this.state.user.name}</div>
        <div>user.age: {this.state.user.age}</div>
        <button onClick={() => this.changeUser()}>change user</button>
      </div>
    );
  }
}

事件绑定

主要有fn1fn2两种写法,目前主流是fn2写法

class App extends React.Component {
  constructor() {
    super();
    this.fn2 = () => {...}    //两处写法等价
  }
  fn1() {...}
  fn2 = () => {...}    //两处写法等价
  render() {
    return (
      <div className="App">
        <button onClick={() => this.fn1()}>fn1</button>
        <button onClick={this.fn2}>fn2</button>
      </div>
    );
  }
}

生命周期

  1. constructor() 要记得super() 在这里初始化state
  2. shouldComponentUpdate() 函数return true 则更新,return false则会阻止更新,可以让我们手动判断是否要进行组件更新,我们可以根据应用场景灵活设置返回值,以避免不必要的更新
  3. render() 创建虚拟DOM
  4. componentDidMount() 组件已出现在页面
  5. componentDidUpdate() 组件已更新
  6. componentWillUnmount() 组件将死