Props介绍与应用

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

什么是 props

props 可以看成一个对外的接口,用来接收外部传入的数据。组件中主要有两种属性 propsstate 无论 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绑定相关推荐

  1. vue中修改props传进来的值

    总所周知,vue是单向数据流,一般我们也不会在子组件里面修改父组件传进来的值,但总有需要修改的时候. 前段时间一个项目中有遇到上述情况,假设我直接传进来一个list, 当时我直接在里面改了list,但 ...

  2. 【vue】修改props传进来的值

    众所周知,vue是单向数据流,一般我们也不会在子组件里面修改父组件传进来的值,但总有需要修改的时候. 前段时间一个项目中有遇到上述情况,假设我直接传进来一个list, 当时我直接在里面改了list,但 ...

  3. react 三种通信方式(父传子、子传父、兄弟传值)

    react有三种通信方式:一.父传子,二.字传父,三.兄弟之间传值 一.父组件向子组件传值 父组件通过属性的方式传递参数,子组件通过props来接收父组件传递过来的参数 React中是单向数据流,数据 ...

  4. React组件通信传值 父传子 子传父 兄弟组件传值

    一.父组件传递子组件 在父组件中引入子组件,将父组件的state值放到子组件标签中传递,在子组件中用this.props.传值名称,接收 父组件代码: import React, { Componen ...

  5. react 子传参父_React 子组件给父组件传值、整个组件、方法

    一.准备工作 1.定义一个父组件,名字为Parent /src/component/Parent.js import React, {Component} from 'react' export de ...

  6. react中实现父传子 子传父 兄弟传值

    1,父组件向子组件传值 父组件 import React, { Component } from 'react' import Child from './Child'export default c ...

  7. React组件通信(父传子,子传父) - 前端

    父组件向子组件传值(通过props传值) 子组件: class Children extends Component{constructor(props){super(props);}render() ...

  8. 子div超出父div_菜鸟学 react props 子到父

    我们都知道在 vue 中可以使用事件将子组件的数据传递给父组件,也可以通过拿到父组件的实例直接调用父组件的方法 先来个子组件 class ChildCom extends React.Componen ...

  9. react 子传参父_React 子组件向父组件传值的方法

    本文介绍了React 子组件向父组件传值的方法,分享给大家 子组件需要控制自己的 state, 然后告诉父组件自己的state,通过props调用父组件中用来控制state的函数,在父组件中展示子组件 ...

最新文章

  1. matlab 绘图3
  2. 青藏高原matlab掩膜,1982~2000年青藏高原地表反照率时空变化特征
  3. JS组件系列——开源免费图表组件:Chart.js
  4. 笔记-项目沟通管理-高效的会议方案
  5. AudioBuffer
  6. Object_C与JavaScript交互使用总结
  7. 为MyEclipse 9/10中的html/JSP编辑器添加代码自动提示
  8. 合并多个txt文件到一个
  9. 图片转换成base64编码格式展示
  10. 自我时间管理与时间意识
  11. 【Unity3D】Unity5打不开VS2017,Unity打开VS2017异常,并且有时候最后打开的是Mono的解决方案
  12. Mac 重置mysql的root 密码
  13. adc芯片资料——电子迷你秤芯片CS1180
  14. IOS屏幕旋转的检测 与 强行切换
  15. SEOer未来发展的两个方向
  16. 【微信小程序】页面配置,网络数据请求
  17. 连接宽带出现:调制解调器出现一个错误
  18. csgo如何录制高清的视频?
  19. C# 调用IP库(QQWry.Dat)查询IP位置及自动升级IP库方法【转】
  20. nRF2401A/nRF24L01/nRF24L01+无线模块最常见问题汇集(转)

热门文章

  1. Occlusion Culling 遮挡剔除 相机系列5
  2. 医疗和牙科3D打印的全球与中国市场2022-2028年:技术、参与者、趋势、市场规模及占有率研究报告
  3. 会员获取积分的方式有哪些?
  4. 普教同步课堂、专递课堂建设解决方案
  5. origin3D作图surface和等高线图contor
  6. [高效学习]之1学习金字塔
  7. 测试/开发程序员值这么多钱么?“我“不会愿赌服输......
  8. 浅谈大数据里的Kafka (9)Kafka的消费方式和消费策略
  9. 昨日种种死 今日种种生
  10. xml与txt文件格式互换