React的Props、生命周期

Props 的只读性

"Props" 是 React 中用于传递数据给组件的一种机制,通常作为组件的参数进行传递。在 React 中,props 是只读 的,意味着一旦将数据传递给组件的 props,组件就不能直接修改这些 props 的值。所以组件无论是使用函数声明还是通过 class 声明,都决不能修改自身的 props。

所以React有一个严格的规则:所有 React 组件都必须像纯函数一样保护它们的 props 不被更改

为什么Props是只读的呢?

当我们在父组件中将数据传递给子组件时,子组件只能使用这些 props 来读取数据,而不能修改它们。这是为了确保数据的单向流动,使得数据的流动更加可控和可预测。当 Props 是只读的时候,我们可以确保数据只能从父组件流向子组件,而子组件不能直接修改父组件传递的数据。这种单向数据流有助于维护组件的可预测性和代码的可维护性。

如果我无法避免要在组件内部修改数据,该怎么办?

如果你需要在组件内部修改数据,你可以使用组件的状态(state)。状态是组件内部的可变数据,可以通过特定的方法来修改。但是这些状态无法直接传递给其他组件,如果需要在多个组件之间共享数据,可以考虑使用上层组件的状态或者全局状态管理工具(如 Redux)

代码示例:

js 复制代码
import React, { useState } from 'react';

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

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

  return (
    <div>
      <h2>父组件</h2>
      <p>Count: {count}</p>
      <ChildComponent count={count} increment={incrementCount} />
    </div>
  );
}

function ChildComponent(props) {
  return (
    <div>
      <h2>子组件t</h2>
      <p>总和: {props.count}</p>
      <button onClick={props.increment}>+1</button>
    </div>
  );
}

export default ParentComponent;

如何将函数组件转换成 class 组件

  1. 创建一个同名的 ES6 class,并且继承于 React.Component
  2. 添加一个空的 render() 方法。
  3. 将函数体移动到 render() 方法之中。
  4. render() 方法中使用 this.props 替换 props
  5. 删除剩余的空函数声明。

函数式组件

js 复制代码
function tick(Props) {
  const element = (
    <div>
      <h1>Hello, world!</h1>
      <h2>It is {Props.time.toLocaleTimeString()}.</h2>
    </div>
  );
  root.render(element);
  }

class组件

js 复制代码
    class Clock extends React.Component {
      render() {
        return (
          <div>
            <h1>Hello, world!</h1>
            <h2>It is {this.props.date.toLocaleTimeString()}.</h2>
          </div>
        );
      }
    }

生命周期

挂载

  • constructor--------组件实例化时执行,用于初始化state和绑定事件等操作

  • getDerivedStateFromProps --------在render方法执行之前调用,用于根据props设置state。

  • render--------渲染组件

  • componentDidMount(-------组件挂载到DOM后执行,用于执行一些需要DOM的操作,如获取数据。

更新

  • getDerivedStateFromProps-------在render方法执行之前调用,用于根据props设置state
  • shouldComponentUpdate------判断组件是否需要重新渲染,默认返回true
  • render------渲染组件
  • getSnapshotBeforeUpdate------在更新前获取DOM信息,如滚动位置等。
  • componentDidUpdate--------组件更新后执行,用于执行一些需要DOM的操作,如更新数据

卸载

  • componentWillUnmount------组件从DOM中移除时经历的阶段

写一个时钟案例,每秒都会更新时间

js 复制代码
    class Clock extends React.Component {
      constructor(props) {
        super(props);
        this.state = {date: new Date()};
      }

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

      componentWillUnmount() {
        clearInterval(this.timerID);
      }

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

      render() {
        return (
          <div>
            <h1>Hello, world!</h1>
            <h2>It is {this.state.date.toLocaleTimeString()}.</h2>
          </div>
        );
      }
    }

    const root = ReactDOM.createRoot(document.getElementById('root'));
    root.render(<Clock />);

让我们来快速概括一下发生了什么和这些方法的调用顺序:

  1. <Clock /> 被传给 root.render()的时候,React 会调用 Clock 组件的构造函数。因为 Clock 需要显示当前的时间,所以它会用一个包含当前时间的对象来初始化 this.state。我们会在之后更新 state。
  2. 之后 React 会调用组件的render()方法。这就是 React 确定该在页面上展示什么的方式。然后 React 更新 DOM 来匹配 Clock 渲染的输出。
  3. Clock的输出被插入到 DOM 中后,React 就会调用 ComponentDidMount() 生命周期方法。在这个方法中,Clock 组件向浏览器请求设置一个计时器来每秒调用一次组件的tick()方法。
  4. 浏览器每秒都会调用一次tick()方法。 在这方法之中,Clock 组件会通过调用 setState() 来计划进行一次 UI 更新。得益于 setState() 的调用,React 能够知道 state 已经改变了,然后会重新调用 render() 方法来确定页面上该显示什么。这一次,render() 方法中的 this.state.date 就不一样了,如此一来就会渲染输出更新过的时间。React 也会相应的更新 DOM。
  5. 一旦 Clock 组件从 DOM 中被移除,React 就会调用 componentWillUnmount() 生命周期方法,这样计时器就停止了。
复制代码
相关推荐
想睡好5 分钟前
css文本属性
前端·css
qianmoQ7 分钟前
第三章:组件开发实战 - 第五节 - Tailwind CSS 响应式导航栏实现
前端·css
记得早睡~13 分钟前
leetcode150-逆波兰表达式求值
javascript·算法·leetcode
zhoupenghui16820 分钟前
golang时间相关函数总结
服务器·前端·golang·time
White graces34 分钟前
正则表达式效验邮箱格式, 手机号格式, 密码长度
前端·spring boot·spring·正则表达式·java-ee·maven·intellij-idea
庸俗今天不摸鱼34 分钟前
Canvas进阶-4、边界检测(流光,鼠标拖尾)
开发语言·前端·javascript·计算机外设
bubusa~>_<1 小时前
解决npm install 出现error,比如:ERR_SSL_CIPHER_OPERATION_FAILED
前端·npm·node.js
[廾匸]1 小时前
cesium视频投影
javascript·无人机·cesium·cesium.js·视频投影
风清云淡_A2 小时前
【react18】如何使用useReducer和useContext来实现一个todoList功能
react.js
流烟默2 小时前
vue和微信小程序处理markdown格式数据
前端·vue.js·微信小程序