React (三) 修改props,React父传子、子传父、this绑定
Props介绍与应用
- 什么是 props
- 如何使用
- 父传子
- 函数组件
- 类组件
- 默认值
- 子传父
- 修改 props
- 事件监听 this 绑定
- 直接在 jsx 元素上进行绑定(不推荐)
- 箭头函数(推荐)
- 直接在 jsx 上使用箭头函数(不推荐)
什么是 props
props
可以看成一个对外的接口,用来接收外部传入的数据。组件中主要有两种属性 props
和 state
无论 props 或者 state 中哪两个发生了改变都会重新引发渲染
如何使用
如果你使用过 Vue,也肯定使用过父传子和子传父的功能,在 react 中也有父子通信。
父传子
函数组件
上一篇文章我讲述了使用[...props]
来进行传值,那是一种简写。
// 父组件
function Component1(){// 创建一个refconst 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(){// 创建一个refconst 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(){// 创建一个refconst 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(){// 创建一个refconst 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
上绑定事件都会出现性能问题。
React (三) 修改props,React父传子、子传父、this绑定相关推荐
- vue中修改props传进来的值
总所周知,vue是单向数据流,一般我们也不会在子组件里面修改父组件传进来的值,但总有需要修改的时候. 前段时间一个项目中有遇到上述情况,假设我直接传进来一个list, 当时我直接在里面改了list,但 ...
- 【vue】修改props传进来的值
众所周知,vue是单向数据流,一般我们也不会在子组件里面修改父组件传进来的值,但总有需要修改的时候. 前段时间一个项目中有遇到上述情况,假设我直接传进来一个list, 当时我直接在里面改了list,但 ...
- react 三种通信方式(父传子、子传父、兄弟传值)
react有三种通信方式:一.父传子,二.字传父,三.兄弟之间传值 一.父组件向子组件传值 父组件通过属性的方式传递参数,子组件通过props来接收父组件传递过来的参数 React中是单向数据流,数据 ...
- React组件通信传值 父传子 子传父 兄弟组件传值
一.父组件传递子组件 在父组件中引入子组件,将父组件的state值放到子组件标签中传递,在子组件中用this.props.传值名称,接收 父组件代码: import React, { Componen ...
- react 子传参父_React 子组件给父组件传值、整个组件、方法
一.准备工作 1.定义一个父组件,名字为Parent /src/component/Parent.js import React, {Component} from 'react' export de ...
- react中实现父传子 子传父 兄弟传值
1,父组件向子组件传值 父组件 import React, { Component } from 'react' import Child from './Child'export default c ...
- React组件通信(父传子,子传父) - 前端
父组件向子组件传值(通过props传值) 子组件: class Children extends Component{constructor(props){super(props);}render() ...
- 子div超出父div_菜鸟学 react props 子到父
我们都知道在 vue 中可以使用事件将子组件的数据传递给父组件,也可以通过拿到父组件的实例直接调用父组件的方法 先来个子组件 class ChildCom extends React.Componen ...
- react 子传参父_React 子组件向父组件传值的方法
本文介绍了React 子组件向父组件传值的方法,分享给大家 子组件需要控制自己的 state, 然后告诉父组件自己的state,通过props调用父组件中用来控制state的函数,在父组件中展示子组件 ...
最新文章
- matlab 绘图3
- 青藏高原matlab掩膜,1982~2000年青藏高原地表反照率时空变化特征
- JS组件系列——开源免费图表组件:Chart.js
- 笔记-项目沟通管理-高效的会议方案
- AudioBuffer
- Object_C与JavaScript交互使用总结
- 为MyEclipse 9/10中的html/JSP编辑器添加代码自动提示
- 合并多个txt文件到一个
- 图片转换成base64编码格式展示
- 自我时间管理与时间意识
- 【Unity3D】Unity5打不开VS2017,Unity打开VS2017异常,并且有时候最后打开的是Mono的解决方案
- Mac 重置mysql的root 密码
- adc芯片资料——电子迷你秤芯片CS1180
- IOS屏幕旋转的检测 与 强行切换
- SEOer未来发展的两个方向
- 【微信小程序】页面配置,网络数据请求
- 连接宽带出现:调制解调器出现一个错误
- csgo如何录制高清的视频?
- C# 调用IP库(QQWry.Dat)查询IP位置及自动升级IP库方法【转】
- nRF2401A/nRF24L01/nRF24L01+无线模块最常见问题汇集(转)
热门文章
- Occlusion Culling 遮挡剔除 相机系列5
- 医疗和牙科3D打印的全球与中国市场2022-2028年:技术、参与者、趋势、市场规模及占有率研究报告
- 会员获取积分的方式有哪些?
- 普教同步课堂、专递课堂建设解决方案
- origin3D作图surface和等高线图contor
- [高效学习]之1学习金字塔
- 测试/开发程序员值这么多钱么?“我“不会愿赌服输......
- 浅谈大数据里的Kafka (9)Kafka的消费方式和消费策略
- 昨日种种死 今日种种生
- xml与txt文件格式互换