首页 > 其他分享 >react数据管理之setState与Props

react数据管理之setState与Props

时间:2023-10-18 13:08:47浏览次数:29  
标签:React Props 更新 react state props 组件 setState


react数据管理之setState与Props

setState调用原理

setState 是 React 中用于更新组件状态(state)的方法。它的调用原理可以分为以下几个步骤:

  1. 状态的改变:当调用 setState 时,React 会将新的状态对象与当前状态对象进行合并(合并过程是浅合并)。React 不会直接修改当前状态对象,而是创建一个新的状态对象,以确保不直接修改状态,从而遵循 React 的不可变性原则。
  2. 触发重新渲染:一旦状态更新完成,React 会调用组件的 render 方法来重新渲染组件。在重新渲染过程中,React 会生成一个新的虚拟 DOM 树(Virtual DOM)。
  3. 虚拟 DOM 比较:React 会将新生成的虚拟 DOM 树与之前的虚拟 DOM 树进行比较,找出两者之间的差异(所谓的变更集合)。
  4. 局部更新:React 将变更集合中的差异应用到实际的 DOM 中,以更新用户界面。这是一个高效的过程,因为 React 仅更新了需要更新的部分,而不是重新渲染整个页面。
  5. 生命周期方法调用:在更新完成后,React 会调用适当的生命周期方法,如 componentDidUpdate,以便开发者可以执行一些操作,例如获取最新的 DOM 元素引用或执行副作用操作。

需要注意的是,由于 setState 是异步的,React 可能会将多次的 setState 调用合并成一次更新,以提高性能。这意味着在一个函数内多次调用 setState 可能不会导致多次重新渲染,而是在函数执行结束后一次性更新状态和重新渲染。

例如,以下代码中的多次 setState 调用会被合并成一次更新:

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

这个特性有时会导致不直观的行为,因此可以使用函数式的 setState 形式来确保状态更新是基于先前的状态的,而不受合并的影响:

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

setState第二个参数

this.setState(newState, callback);

  • newState 是一个对象或函数,用于描述要更新的状态。这可以是一个新的状态值或一个函数,该函数接受前一个状态作为参数,返回新的状态。
  • callback 是一个可选的回调函数,它会在状态更新完成后被调用。

例如:

import React, { Component } from 'react';

class Counter extends Component {
  constructor(props) {
    super(props);
    this.state = {
      count: 0,
    };
  }

  handleIncrement = () => {
    this.setState({ count: this.state.count + 1 }, () => {
      // 回调函数,会在状态更新后被调用
      console.log('Count updated:', this.state.count);
    });
  }

  render() {
    return (
      <div>
        <p>Count: {this.state.count}</p>
        <button onClick={this.handleIncrement}>Increment</button>
      </div>
    );
  }
}

在上述示例中,当点击按钮并调用 handleIncrement 方法时,this.setState 用于增加 count 的值。回调函数通过 console.log 输出更新后的 count 值,这是在状态更新后被调用的。

回调函数的主要用途包括:

  • 执行需要在状态更新后立即执行的代码。
  • 执行副作用操作,如发起网络请求或操作 DOM。
  • 在状态更新后通知其他组件或触发其他操作。

props和state区别

props(属性)和 state(状态)是 React 中用于管理组件数据的两个不同概念,它们有以下主要区别:

  1. 来源
  • props:是由父组件传递给子组件的数据。父组件通过属性(props)将数据传递给子组件,子组件不可以直接修改这些数据,它们是只读的。
  • state:是组件内部维护的数据,用于描述组件的特定状态。组件可以自己管理和修改自己的状态。
  1. 可变性
  • props:是不可变的(immutable),子组件不能直接修改从父组件接收的 props。Props 用于从外部传递信息给组件,组件应该将 props 视为只读数据。
  • state:是可变的(mutable),组件可以通过调用 setState 方法来更新自己的状态。
  1. 管理
  • props:由父组件管理和传递,子组件只能访问和使用 props。
  • state:由组件自己管理和维护,组件可以在需要时修改自己的状态。
  1. 作用
  • props:用于传递数据给子组件,以控制子组件的行为和显示。
  • state:用于管理组件内部的状态,以响应用户交互、数据请求、或其他事件。
  1. 传递
  • props:通过组件的属性(props)传递给子组件。父组件可以通过属性来控制子组件的行为。
  • state:在组件内部声明和管理,可以通过 setState 方法来更新。
  1. 默认值
  • props:可以为 props 设置默认值,以防止未传递某个属性时出现错误。
  • state:可以在组件的构造函数中设置初始状态(state)的默认值。
  1. 更新
  • props:当父组件的 props 发生变化时,会触发子组件的重新渲染,子组件会接收新的 props。
  • state:当组件的状态(state)发生变化时,会触发组件的重新渲染,从而更新界面。

props改变后如何更新组件

class组件

  1. 父组件传递新的 props:父组件可以通过修改传递给子组件的 props 数据来引发子组件的更新。这可以通过在父组件中修改 props 值或通过父组件的状态变化来实现。
  2. 子组件的 componentWillReceiveProps(已废弃,不推荐使用)、getDerivedStateFromPropscomponentDidUpdate 方法:当子组件接收到新的 props 后,React 将触发这些生命周期方法之一,具体取决于 React 版本和组件实现。
  • 在 React 16.3 及更早版本中,可以使用 componentWillReceiveProps 生命周期方法来处理新的 props
  • 在 React 16.3 及以后的版本中,推荐使用 getDerivedStateFromProps 静态方法或 componentDidUpdate 来处理新的 props
  1. 在生命周期方法中更新组件状态或执行其他操作:在上述生命周期方法中,可以访问新的 props 和组件当前的状态(this.propsthis.state)以及之前的 propsstate。可以根据新的 props 数据来更新组件的状态,从而触发重新渲染。

例如,使用 getDerivedStateFromProps来处理新的 props:

class MyComponent extends React.Component {
  static getDerivedStateFromProps(nextProps, prevState) {
    // 检查新的 props,并根据需要更新状态
    if (nextProps.someProp !== prevState.someProp) {
      return {
        someState: nextProps.someProp,
      };
    }
    return null; // 不更新状态
  }

  render() {
    // 渲染组件
    return <div>{this.state.someState}</div>;
  }
}

或者componentDidUpdate:

import React, { Component } from 'react';

class MyComponent extends Component {
  state = {
    count: 0,
  };

  componentDidUpdate(prevProps, prevState) {
    if (this.props.someProp !== prevProps.someProp) {
      console.log('Props changed:', prevProps.someProp, '->', this.props.someProp);
    }
  }

  render() {
    return <div>{this.props.someProp}</div>;
  }
}

export default MyComponent;

React 16.3 及以后的版本,componentWillReceiveProps 生命周期方法已经被标记为已废弃,不再推荐使用。相反,推荐使用 getDerivedStateFromPropscomponentDidUpdate 来处理 props 的变化。

函数组件

在函数组件中,可以使用 React 的钩子函数来判断组件何时更新,特别是 useEffect 钩子。下面是如何在函数组件中判断组件何时更新:

  1. 使用 useEffect 钩子:使用useEffect 钩子可以函数组件中执行副作用操作,并且可以根据依赖项来判断何时触发这些副作用。可以将 props 或其他状态值作为依赖项,当这些依赖项发生变化时,useEffect 中的代码将被执行。
import React, { useEffect } from 'react';

function MyComponent(props) {
  // 使用 useEffect 钩子来判断何时更新
  useEffect(() => {
    // 这里的代码在组件每次渲染后都会执行

    // 可以在这里根据新的 props 进行操作
    console.log('Props updated:', props.someProp);
  }, [props.someProp]); // 仅在 props.someProp 发生变化时执行

  return <div>{props.someProp}</div>;
}

在上面的示例中,我们将 props.someProp 作为 useEffect 的依赖项,因此当 props.someProp 发生变化时,useEffect 中的代码将被执行,从而可以判断组件何时更新。

  1. 使用 React.memo(可选):如果希望函数组件在特定 props 变化时才进行更新,并且不关心其他的 props,可以使用 React.memo 来包装函数组件。这将创建一个经过优化的组件,只有在指定的 props 发生变化时才会触发重新渲染。
import React from 'react';

function MyComponent(props) {
  return <div>{props.someProp}</div>;
}

// 使用 React.memo 包装组件,只有 someProp 变化时才重新渲染
export default React.memo(MyComponent);

标签:React,Props,更新,react,state,props,组件,setState
From: https://blog.51cto.com/u_14196886/7916306

相关文章

  • react 公司项目学习 【react+webpack+nw.js + mobx+react-intl 实现的多页面多语言win
    这几天突然要来个react项目;听说还比较复杂;项目组内就两个人会react还在忙,整组主要是用vue;这不,这种‘狗都不干’的事,被安排到我身上了,那就学吧;一、研究代码结构不得不说,这目录结构搞得有点复杂,算是我接触中除了乾坤和electron之外,相当复杂的了,慢慢阅读吧;看懂了,原来是react+web......
  • react native app 图标在安卓上内容被切割问题记录
    问题背景:reactnative开发app,设置的app图标在安卓中会被切割,导致周围的留白被切掉,看起来很奇怪。甚至有些文字内容被切割掉,显示不全。在不同手机上,icon可能会被切割成各种圆角,如果留白不够,内容可能会被切割。在iOS上icon也有相应的规范,比如需要1024尺寸等。解决方法:在查找......
  • 在react项目中结合antd实现表格tooltip提示
    react项目antdesign给表格title添加tooltip提示效果,效果如下: title:()=>(    <span>     {'原表'}&nbsp;     <Tooltip       title={'如有颜色标注则表示id在该表无数据'}     >      <InfoCircleOutlined......
  • 26 组件传递props校验
    基于组件传递,对传输的内容进行校验1.设置默认值default2.必选项require3.传参的类型ps:props是只读的,不能修改......
  • React学习笔记04-JSX语法
    1.JSX语法JSX将HTML语法直接加入到JavaScript代码中,再通过翻译器转换到纯JavaScript后由浏览器执行。在实际开发中,JSX在产品打包阶段都已经编译成纯JavaScript,不会带来任何副作用,反而会让代码更加直观并易于维护。编译过程由Babel的JSX编译器实现。 2.JSX语法的......
  • React-Admin后台管理模板|react18+arco+zustand后台解决方案
    基于react18.x+vite4+arco-design自研中后台管理系统解决方案ReactAdmin。react-vite-admin基于vite4搭建react18.x后台管理项目。使用了react18hooks+arco.design+zustand+bizcharts等技术实现权限管理模板框架。支持暗黑/亮色主题、i18n国际化、动态权限鉴定、3种布局模板、t......
  • React-redux 中useSelector使用
    在一个action被分发(dispatch)后,useSelector()默认对select函数的返回值进行引用比较===,并且仅在返回值改变时触发重渲染。但是,不同于connect(),useSelector()并不会阻止父组件重渲染导致的子组件重渲染的行为,即使组件的props没有发生改变。useSelector源码分析import......
  • React学习笔记03-编写第一个react应用程序
    react开发需要引入多个依赖文件:react.js,react-dom.js,分别又有开发版本和生成版本,creat-react-app里已经帮我们把这些东西都安装好了。把通过CRA创建的工程目录下的src目录情况,然后在里面重新创建一个index.js写入以下代码。//从react的包当中引入了React。只要你要写React.j......
  • React学习笔记02-创建React项目
    1.全局安装create-react-appnpminstall-gcreate-reat-app2.创建一个React项目create-react-appmyapp 注意命名规范不能大写,中文等如果不想全局安装,可以直接使用npxnpxcreate-react-appmyapp 需要等待一段时间,这个过程实际上会安装三个东西react:react的顶级......
  • React学习笔记01-React的基本认识
    1.React起源与发展React起源于Facebook的内部项目,因为该公司对市场上所有JavaScriptMVC框架,都不满意,就决定自己写一套,用来架设Instagram的网站。做出来以后,发现这套东西很好用,就在2013年5月开源了。2.React与传统MVC的关系轻量级的视图层库!AJavaScriptlibraryfor......