React (三) 修改props,React父传子、子传父、this绑定

2023-10-31

什么是 props

props 可以看成一个对外的接口,用来接收外部传入的数据。组件中主要有两种属性 propsstate 无论 props 或者 state 中哪两个发生了改变都会重新引发渲染

如何使用

如果你使用过 Vue,也肯定使用过父传子和子传父的功能,在 react 中也有父子通信。

父传子

函数组件

上一篇文章我讲述了使用[...props] 来进行传值,那是一种简写。

// 父组件
function Component1(){
    // 创建一个ref
    const porps = {name: 'ccc',age:18};
  	const a = {h: 'ccc'};
    return (
        <div style={divStyles} title={divTitles} className="App" tab-index="1">
            <User {...porps} />    {/* 使用简写 */}
            <User name='我没有用简写' age='18' />
              {/* 如果是非字符串 就要用大括号*/}
						<User name='我没有用简写' age='18' title={a}/>
        </div>
    );
}
// 通过参数去接受值
function User(props){
    return(
        <div>
            <h2>我是user组件</h2>
            <p>{props.name}---{props.age}</p>
        </div>

    );
}

上面的代码中就是简写和非简写的区别。可以直接在组件编写属性的方式传参数,在用 props 去接收参数。

我们都知道react在没有 hook 之前他们两个的区别主要在于有无 state 和生命周期,类组件可以使用生命周期和构造函数,而函数组件中只有 props,函数组件也称为无状态组件。类组件如果有 state 就是有状态组件,没有 state 就是无状态组件。如果类组件没有 state 推荐使用函数组件(函数组件效率高于类组件)。有了 hook 之后 在函数组件组件里面也可以使用 state

类组件

类组件中如何传值

// 定义一个函数组件和写内联样式
// 父组件
function Component1(){
    // 创建一个ref
    const porps = {name: 'ccc',age:18};
  	const a = {h: 'ccc'};
    return (
        <div style={divStyles} title={divTitles} className="App" tab-index="1">
            <User {...porps} />    {/* 使用简写 */}
            <User name='我没有用简写' age='18' />
              {/* 如果是非字符串 就要用大括号*/}
						<User name='我没有用简写' age='18' title={a}/>
        </div>
    );
}

// 类组件 props 被实例化了 可以直接使用this.去访问之后在结构
class Footer extends React.Component {
    render() {
        const {name,age} =this.props;
        return(
            <div>
                <h1>我是一个类组件{name}---{age}</h1>
            </div>
        );
    }
}

默认值

可以通过 defaultProps 设置默认值

// 父组件
function Component1(){
    // 创建一个ref
    const porps = {name: 'ccc',age:18};
  	const a = {h: 'ccc'};
    return (
        <div style={divStyles} title={divTitles} className="App" tab-index="1">
            
            <User/>
              {/* 如果是非字符串 就要用大括号*/}
						<User name='我没有用简写' age='18' title={a}/>
        </div>
    );
}

// 子组件
function User(props){
    return(
        <div>
            <h2>我是user组件</h2>
            <p>{props.name}---{props.age}</p>
        </div>

    );
}

User.defaultProps = {
    age: 20,
    name: 'xxx'
};

子传父

props 可以接受任意类型的值。我们可以利用这个特性来实现子组件到父组件的传值,我们可以传递一个函数,通过函数传参的方式,来实现这一功能。这里使用的 this 绑定方式这里查看介绍

// 父组件
function Component1(){
    // 创建一个ref
    const userRef = React.createRef();
    const porps = {name: 'ccc',age:18};
    function getData(data){
        console.log('我是接受接受到子组件的值', data);
    }
    return (
        <div style={divStyles} title={divTitles} className="App" tab-index="1">
            <Footer {...porps} getData={getData} ref={userRef}></Footer>
        </div>
    );
}


// 子组件
class Footer extends React.Component {
    constructor(props){
        super(props);
        // 组件内部的状态 通过 setState 方法来更改的
        this.state = {
            name1:props.name+'ttt',
            num: 0
        };
    }
    add = () => {
        this.setState(state =>({
            num: ++state.num,
        }));
        this.props.getData(this.state.num);
    }
    render() {
        const {name,age} =this.props;
        return(
            <div>
                <h1>我是一个类组件{this.state.name1}---{age}</h1>
                <button onClick={this.add}>点我加一{this.state.num}</button>
            </div>
        );
    }
}

修改 props

在 React 中我们不能直接修改 props

// 子组件
function User(props){
  props.name = 'ttt';
    return(
        <div>
            <h2>我是user组件</h2>
            <p>{props.name}---{props.age}</p>
        </div>

    );
}
// 第三行报错

上面的代码会报错,props 是个只读属性。在 react 中数据流是单向的,不能改变一个组件在渲染是传进来的 props。因为组件会复用,如果可以修改 props,结果会不可预测,也违背了组件的设计原则,但是这并不代表在 props 不能修改**。**

可以通过 state 来变相修改 props。state 可以理解为中间人,主要是利用了 react 里面的重新渲染(setState)方式把props传入到组件中,在通过赋值到 state,在来修改。

// 父组件
function Component1(){
    const userRef = React.createRef();
    const porps = {name: 'ccc',age:18};
    return (
        <div style={divStyles} title={divTitles} className="App" tab-index="1">
            <Footer {...porps} ref={userRef}></Footer>
        </div>
    );
}

// 子组件
class Footer extends React.Component {
  // constructor是构造器函数,如果没有申明,会自动添加,而且只会执行一次
  constructor(props){
  	super(props);
    // 组件内部的状态 通过 setState 方法来更改的
    this.state = {
    	name1:props.name+'ttt'
    }
  }
    render() {
        const {name,age} =this.props;
        return(
            <div>
                <h1>我是一个类组件{this.state.name1}---{age}</h1>
            </div>
        );
    }
}

constructor 里面除了修改 props 还可以进行函数绑定

// 父组件
function Component1(){
    const userRef = React.createRef();
    const porps = {name: 'ccc',age:18};
    return (
        <div style={divStyles} title={divTitles} className="App" tab-index="1">
            <Footer {...porps} ref={userRef}></Footer>
        </div>
    );
}

// 子组件
class Footer extends React.Component {
    constructor(props){
        super(props);
        // 组件内部的状态 通过 setState 方法来更改的
        this.state = {
            name1:props.name+'ttt',
            num: 0
        };
        this.add = this.add.bind(this);
    }
    add(){
        this.setState(state =>({
            num: ++state.num,
        }));
    }
    render() {
        const {name,age} =this.props;
        return(
            <div>
                <h1>我是一个类组件{this.state.name1}---{age}</h1>
                <button onClick={this.add}>点我加一{this.state.num}</button>
            </div>
        );
    }
}

事件监听 this 绑定

this 一共有四种绑定方式,一种就是我上面说的在 constructor 使用 bind 绑定。而且这种方法也是官方推荐的。

下面我来介绍其他三种

直接在 jsx 元素上进行绑定(不推荐)

// 父组件
function Component1(){
    const userRef = React.createRef();
    const porps = {name: 'ccc',age:18};
    return (
        <div style={divStyles} title={divTitles} className="App" tab-index="1">
            <Footer {...porps} ref={userRef}></Footer>
        </div>
    );
}

// 子组件
class Footer extends React.Component {
    constructor(props){
        super(props);
        // 组件内部的状态 通过 setState 方法来更改的
        this.state = {
            name1:props.name+'ttt',
            num: 0
        };
    }
    add(){
        this.setState(state =>({
            num: ++state.num,
        }));
    }
    render() {
        const {name,age} =this.props;
        return(
            <div>
                <h1>我是一个类组件{this.state.name1}---{age}</h1>
                <button onClick={this.add.bind(this)}>点我加一{this.state.num}</button>
            </div>
        );
    }
}

上面代码中我们直接在 button 上进行了绑定。但是这样子会出现一个问题,就是每次在渲染组件的时候,都会创建一个新的函数。会造成额外的渲染,影响性能。

箭头函数(推荐)

使用了 ES6 的类字段

// 父组件
function Component1(){
    const userRef = React.createRef();
    const porps = {name: 'ccc',age:18};
    return (
        <div style={divStyles} title={divTitles} className="App" tab-index="1">
            <Footer {...porps} ref={userRef}></Footer>
        </div>
    );
}

// 子组件
class Footer extends React.Component {
    constructor(props){
        super(props);
        // 组件内部的状态 通过 setState 方法来更改的
        this.state = {
            name1:props.name+'ttt',
            num: 0
        };
    }
    add = () => {
        this.setState(state =>({
            num: ++state.num,
        }));
    }
    render() {
        const {name,age} =this.props;
        return(
            <div>
                <h1>我是一个类组件{this.state.name1}---{age}</h1>
                <button onClick={this.add}>点我加一{this.state.num}</button>
            </div>
        );
    }
}

因为箭头函数本身没有 this 属性,所以他的 this 指向的是 Footer 这个类本身,这个方法是推荐的因为不会存在多重绑定的问题。

直接在 jsx 上使用箭头函数(不推荐)

// 父组件
function Component1(){
    const userRef = React.createRef();
    const porps = {name: 'ccc',age:18};
    return (
        <div style={divStyles} title={divTitles} className="App" tab-index="1">
            <Footer {...porps} ref={userRef}></Footer>
        </div>
    );
}

// 子组件
class Footer extends React.Component {
    constructor(props){
        super(props);
        // 组件内部的状态 通过 setState 方法来更改的
        this.state = {
            name1:props.name+'ttt',
            num: 0
        };
    }
    add = () => {
        this.setState(state =>({
            num: ++state.num,
        }));
    }
    render() {
        const {name,age} =this.props;
        return(
            <div>
                <h1>我是一个类组件{this.state.name1}---{age}</h1>
                <button onClick={() => {
                    this.setState(state =>({
                        num: ++state.num,
                    }));
                }}>点我加一{this.state.num}</button>
            </div>
        );
    }
}

直接在 jsx 上使用箭头函数会导致和直接在 jsx 上进行绑定一样的问题就是每次在渲染组件的时候,都会创建一个新的函数。会造成额外的渲染,影响性能。事件只要是在 render 上绑定事件都会出现性能问题。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

React (三) 修改props,React父传子、子传父、this绑定 的相关文章

  • Exceljs:迭代每行和每列的每个单元格

    我想在所有单元格中添加粗边框 这是一个有角度的项目 我正在使用打字稿 我可以为 1 个单元格做到这一点 worksheet getCell A1 border top style thick left style thick bottom
  • 整个页面都是玻璃板

    有没有一种简单的方法可以在整个 HTML 页面上拥有一个 玻璃窗格 而不管缩放 幻灯片事件 平台 浏览器 移动 桌面 我所说的 简单 是指纯 CSS 支持 而不是插件 后备 插件建议也可能有用 Thanks 如果您只是指所有内容之上的一层
  • 流媒体性能 - Canvas 与

    我正在开发一个应用程序 需要通过 webSocket 连接以每秒至少 30 帧的速度持续传输图像 我遇到了一些性能问题 并希望尽我所能进行优化 我想知道使用不断更新的图像之间的性能差异是什么 就像这样 img src someDynamic
  • Node.js Google-云存储上传目的地规范

    我有一个 Node js 服务器并且正在使用谷歌云上传一些图像文件的包Firebase 存储 上传本身工作正常 但 google cloud API 似乎只能将文件上传到 Firebase Storage 根文件夹 有没有办法指定远程位置来
  • 使用 Charts.js 禁用动画

    我在使用 Charts js 关闭动画时遇到一些问题 这是我的代码 var pieData value 30 color F38630 value 50 color E0E4CC value 100 color 69D2E7 var myP
  • 强制执行 show.bind

    我有一个包含数据的表 当从另一个视图触发事件时 我希望视图检查 show bind 语句 问题是该事件没有更改当前视图中的任何数据 foo html tr p canBeRemoved p tr 我正在使用 EventAggregator
  • 尝试使用 CasperJS 跟踪 iframe 中的链接

    我正在尝试使用CasperJS http casperjs org index html跟踪 iframe 中的链接 但我似乎无法获取 iframe 的文档 这是使用我找到的 iframe 示例页面进行的测试 第三个 iframe 有一个名
  • 我什么时候应该使用内联和外部 Javascript?

    我想知道什么时候应该包含外部脚本或将它们与 html 代码内联编写 就性能和易于维护而言 这方面的一般做法是什么 真实场景 我有几个需要客户端表单验证的 html 页面 为此 我使用了一个包含在所有这些页面上的 jQuery 插件 但问题是
  • React JS“this”没有按预期工作

    我有下面的代码 save function var this this console log this refs itemText this setState isEditing false function console log In
  • 元素在主体内找不到足够的空间 - JavaScript 样式

    相关信息 该页面包含两个元素 An
  • jQuery 如何通过不同的列值计算表中的行数

    如何按表列计算不同的表行 Example table thead tr th NAME th th TECHNOLOGY th tr thead tbody tr td john td td jQuery td tr tr td mark
  • 使用 jQuery 更改 SVG 元素的“xlink:href”属性

    我正在尝试使用单击事件更改 xlink href 属性 到目前为止它部分有效 这就是我正在做的 HTML a href class ui btn ui corner all ui shadow editIcon style text ali
  • 如何使用javascript从特定标签获取HTML文档中的所有textNode?

    如何在不使用xpath或treewalker的情况下从单个数组中的一组特定标签中获取所有textNodes blockquote em h4 h6 p IE不允许您使用xpath和treewalker 请帮助我 如果脚本仅适用于 IE 那就
  • 调用不带括号的 javascript 函数

    以下 renderChat 函数用于将消息和图像渲染到聊天板上 该函数内部还有另一个函数 var onComplete function 它完成创建列表元素并将其附加到聊天列表的所有工作 onComplete函数之后就只有这三行代码 img
  • JavaScript 按名称获取当前作用域中的变量

    所以我有一个变量和该变量名称的字符串 function Factory string var foo bar console log foo is equal to this string 如果变量所在的对象是当前对象 如何从字符串文字中获
  • 按钮导致页面重新加载

    我在我的页面上使用 html 和 jquery 在我的 html 中 我有一个按钮 单击该按钮将触发一个功能 当页面加载时 我调用文档准备中的主函数 这是我的代码 div div
  • 加载 angularjs 路由后运行 javascript 代码

    我需要在 angularjs 加载路线后显示警报 显示警报的代码位于 angularjs 异步加载的视图中 视图加载后 我希望它能够运行 但它没有 我知道我可以广播并告诉它稍后运行等 但我需要一个更通用的解决方案 假设您正在谈论基于以下内容
  • Modernizr 未将类应用于 html 标签

    我目前正在构建一个网站 我需要使用 Modernizr 但由于某种原因 它没有将类应用到 html 标签 因为它应该 我的代码如下所示
  • 保留对 React 状态变量的“引用”

    据我所知 Javascript 中没有指针 我有以下问题 但我想知道是否有一个解决方案让我无法解决 解决方案可能是普通的 Javascript 或者像 Context API 这样的 React js 钩子 useContext 或者更多
  • 使用 Three.js 中的设备方向控件进行对象旋转

    我正在迈出使用 JavaScript 进行编码并使用 Three js 的第一步 我正在尝试 Threejs org 的这个例子 http trijs org examples misc controls deviceorientation

随机推荐

  • Python 十大装 B 语法【Python干货】

    Python 是一种代表简单思想的语言 其语法相对简单 很容易上手 不过 如果就此小视 Python 语法的精妙和深邃 那就大错特错了 本文精心筛选了最能展现 Python 语法之精妙的十个知识点 并附上详细的实例代码 如能在实战中融会贯通
  • Exception 处理之最佳实践

    作者 Gunjan Doshi 2003 11 19 译者注 本文算是一篇学习笔记 仅供学习参考使用 有不妥之处 还请指出 2003 12 04 本文是Exception处理的一篇不错的文章 从Java Exception的概念介绍起 依次
  • L3 Hive操作

    示例 1 建表 create table t dml detail id bigint sale date date province string city string product id bigint cnt double amt
  • Yarn的安装详解?Yarn的各种系统安装详解

    2019独角兽企业重金招聘Python工程师标准 gt gt gt 如何在不同系统环境中安装Yarn Yarn在各种系统的安装详解 Yarn的安装详细的教程 希望能帮助一些程序袁 工具 原料 电脑 Yarn Windows安装详解 1 可以
  • NJUPT南邮

    设计可用于该实验的进程控制块 进程控制块至少包括进程号 状态和要求服务时间 动态或静态创建多个进程 模拟操作系统四种进程调度算法 先进先出 短作业优先 高优先级优先 高相应比优先中的任意两种 调度所创建的进程并显示调度结果 package
  • matlab2021版关于csv文件读写的一些方法

    首先给出一些演示数据 直接给出来大家看起来都方便 完整代码在最后 有基础的可以直接看代码 下面是data csv的文件内容 可以看得出里面有文本也有数值 代码 名称 最新价 涨跌额 涨跌幅 买入 卖出 昨收 今开 最高 最低 成交量 成交额
  • MySQL binlog 日志解析

    很多时候 当我们的业务数据产生了不正常的变化 但却无法得知这类操作是在哪里进行 并且如何进行 单单从程序当面排查很费力 那么就需要通过分析数据库日志来得到历史执行 SQL 根据 SQL 执行逻辑来确认代码位置 进而确认是否是 BUG 亦或是
  • configure –prefix 的用法

    源码的安装一般由有这三个步骤 配置 configure 编译 make 安装 make install 其中 prefix选项就是配置安装的路径 如果不配置该选项 安装后可执行文件默认放在 usr local bin 库文件默认放在 usr
  • spring boot 根据模板生成新的文件(exec),复杂一点的,新的导出

  • Timesat提取物候信息并绘图

    Timesat提取物候信息并绘图 前言 一 准备数据 1 将 Tiff 数据转成 dat 数据并生成 Filelist 2 使用python生成单个像素点text时序数据 二 Timesat 打开时序数据 1 处理dat文件 提取物候信息
  • Windows 随意切换node版本

    第一步 先清空本地安装的node js版本 卸载 删除 第二步 安装nvm管理工具 先关掉360等软件 不然会弹出警告 1 从官网下载安装包 https github com coreybutler nvm windows releases
  • Java实现微信扫码登录并实现认证授权

    Java实现微信扫码登录并实现认证授权 1 登录流程及原理 1 1 OAuth2协议 网站应用微信登录是基于OAuth2 0协议标准构建的微信OAuth2 0授权登录系统 在进行微信OAuth2 0授权登录接入之前 在微信开放平台注册开发者
  • java中的date_Java中Date类型详解

    一 Date类型的初始化 1 Date int year int month int date 直接写入年份是得不到正确的结果的 因为java中Date是从1900年开始算的 所以前面的第一个参数只要填入从1900年后过了多少年就是你想要得
  • Spring:IOC控制反转、@Bean和@Component、日志、注入、注解

    Spring核心知识点 Spring 核心功能 IOC 控制反转 和 AOP 面向切面编程 一 什么是IOC Inversion of Control 控制反转 1 主动控制 2 控制反转 二 使用原生Spring创建Demo项目 1 导入
  • 基于python的opencv入门到精通(一)

    记录自己从0开始成长的研究生生活 文章目录 前言 一 Anaconda是什么 二 已经安装了python如何与Anaconda共存 三 如何将PyCharm与Anaconda进行关联 四 配置Anaconda源 五 如何彻底删除python
  • 使用tf.data.Dataset.from_tensor_slices五步加载数据集

    前言 最近在学习tf2 数据加载感觉蛮方便的 这里记录下使用 tf data Dataset from tensor slices 进行加载数据集 使用tf2做mnist kaggle 的代码 思路 Step0 准备要加载的numpy数据
  • 记:判断字符串中空格字符的个数

    描述 输入一行可能带空格的字符串 输入其中空格字符的数量 输入 只有一组案例 一行可能带空格的字符串s 输出 一个正整数 表示字符串s里空格字符的数量 不要换行 样例输入 abc xyz 样例输出 1 法一 string include
  • 别只知道JVM 而不知道JMM

    JAVA 内存模型 JMM 内存模型概念 在特定的操作协议下 对特定的内存或高速缓存进行读写访问的过程抽象 JMM 主要就是因为CPU的多核多级缓存 为了优化代码而进行的指令重排序 从而处理器会对代码乱序的问题 保证最终的并发安全 JMM是
  • ROS与STM32F407实现消息通信(含源码)

    关注微信公众号 混沌无形 后台回复 13462EE 免费获取完整工程源码 本文参考STM32F1与ROS的通信工程 https blog csdn net qq 36349536 article details 82773064 针对STM
  • React (三) 修改props,React父传子、子传父、this绑定

    Props介绍与应用 什么是 props 如何使用 父传子 函数组件 类组件 默认值 子传父 修改 props 事件监听 this 绑定 直接在 jsx 元素上进行绑定 不推荐 箭头函数 推荐 直接在 jsx 上使用箭头函数 不推荐 什么是