【前端】touch React little further | 来自freeCodeCamp

70 阅读3分钟

有状态属性的组件,props像传入的参数,state更像组件的“内存”。

// 创建状态(state) 
// 通过继承 React.Component,类组件可创建state,在类内任意调用
class StatefulComponent extends React.Component {
  constructor(props) {
    super(props);
    // 只修改这一行下面的代码
    this.state = {
      firstName: 'Wang'
    }
    // 只修改这一行上面的代码
  }
  render() {
    const name=this.state.name;
    return (
      <div>
        {/*也可以填入上方Render内定义的 name 变量*/}
        <h1>{this.state.firstName}</h1>
      </div>
    );
  }
};
------------------
// React 要求永远不要直接修改 state,而是在 state 发生改变时始终使用 this.setState()。
this.setState({
  username: 'Lewis'
});
------------------
// 有时,在更新状态时,您可能需要知道以前的状态。然而,状态更新可能是异步的-这意味着
// React可以将多个setState()调用批处理到单个更新中。这意味着在计算下一个值时不能
// 依赖于this.state或this.props的前一个值。所以,你不应该使用这样的代码:

this.setState({
  counter: this.state.counter + this.props.increment
});
// 正确的做法是,给 setState 传入一个函数,这个函数可以访问 state 和 props。 
// 给 setState 传入函数可以保证 state 和 props 是正确的值。 代码可以重写为这样:

this.setState((state, props) => ({
  counter: state.counter + props.increment
}));
------------------review
// Counter 组件跟踪 state 中的 count 值。 有两个按钮分别调用 increment() 和 decrement() 方法。
// 编写这些方法,使计数器值在单击相应按钮时增加或减少 1。 另外,创建一个 reset() 方法,当单击 
// reset 按钮时,把计数设置为 0。
class Counter extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      count: 0
    };
    // 修改这行下面的代码
    this.increment = this.increment.bind(this); // 创建绑定
    this.decrement = this.decrement.bind(this);
    this.reset = this.reset.bind(this);
    // 修改这行上面的代码
  }
  // 修改这行下面的代码
  increment() {
    this.setState((state) => ({
      count: state.count + 1
    }));
  }
  decrement() {
    this.setState((state) => ({
      count: state.count - 1
    }));
  }
  reset() {
    this.setState((state) => ({
      count: 0
    }));
  }
  // 修改这行上面的代码
  render() {
    return (
      <div>
        <button className='inc' onClick={this.increment}>Increment!</button>
        <button className='dec' onClick={this.decrement}>Decrement!</button>
        <button className='reset' onClick={this.reset}>Reset</button>
        <h1>Current Count: {this.state.count}</h1>
      </div>
    );
  }
};

合state进行更复杂的UI交互

// 与输入框联动
class ControlledInput extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      input: ''
    };
    // 修改这行下面的代码
    this.handleChange = this.handleChange.bind(this);
    // 修改这行上面的代码
  }
  // 修改这行下面的代码
  handleChange(event) {
    this.setState({
      input: event.target.value
    })
  }
  // 修改这行上面的代码
  render() {
    return (
      <div>
        { /* 修改这行下面的代码 */}
        <input value={this.state.input} 
               onChange={this.handleChange}/>
        { /* 修改这行上面的代码 */}
        <h4>Controlled Input:</h4>
        <p>{this.state.input}</p>
      </div>
    );
  }
};

Q:react现在是否还以class组件为主?还是以函数组件为主

A: 类组件(Class Components)

类组件是React早期版本中创建组件的主要方式。它们是ES6类的实例,继承自React.Component,并包含一个render()方法,该方法返回JSX。

定义和语法: 类组件使用ES6类语法定义,需要继承自React.Component,并在类中实现render()方法。例如:

jsx
class Greeting extends React.Component {
  render() {
    return <h1>Hello, {this.props.name}</h1>;
  }
}

状态管理: 类组件通过this.statethis.setState()管理内部状态。

生命周期方法: 类组件提供了多种生命周期方法,如componentDidMountcomponentDidUpdatecomponentWillUnmount,允许开发者在组件生命周期的不同阶段执行副作用。

引用处理: 类组件通常使用React.createRef()来处理引用,从而可以直接访问DOM元素。

性能: 由于类组件的额外开销,如类实例化和方法调用,它们的性能通常略低于函数组件。

函数组件(Functional Components)

函数组件是React中较新的组件形式,它们本质上是JavaScript函数,接收props作为参数,并返回JSX。

定义和语法: 函数组件使用JavaScript函数定义,更简洁,易于理解。例如:

jsx
function Greeting(props) {
  return <h1>Hello, {props.name}</h1>;
}

Hooks: 自React 16.8起,函数组件通过Hooks获得了管理状态和副作用的能力。例如,useState用于状态管理,useEffect用于生命周期方法。

简化语法: 函数组件避免了类组件中this的复杂性,代码更简洁。

性能: 函数组件通常提供更好的性能,因为它们避免了类继承的开销。

社区偏好: 根据社区使用趋势,函数组件的使用率从2018年的45%增长到2022年的92%,显示出明显的增长趋势。