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

您所在的位置:网站首页 react父组件触发子组件方法 React (三) 修改props,React父传子、子传父、this绑定

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

2024-07-15 21:44| 来源: 网络整理| 查看: 265

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

什么是 props

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

如何使用

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

父传子 函数组件

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

// 父组件 function Component1(){ // 创建一个ref const porps = {name: 'ccc',age:18}; const a = {h: 'ccc'}; return ( {/* 使用简写 */} {/* 如果是非字符串 就要用大括号*/} ); } // 通过参数去接受值 function User(props){ return( 我是user组件 {props.name}---{props.age} ); }

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

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

类组件

类组件中如何传值

// 定义一个函数组件和写内联样式 // 父组件 function Component1(){ // 创建一个ref const porps = {name: 'ccc',age:18}; const a = {h: 'ccc'}; return ( {/* 使用简写 */} {/* 如果是非字符串 就要用大括号*/} ); } // 类组件 props 被实例化了 可以直接使用this.去访问之后在结构 class Footer extends React.Component { render() { const {name,age} =this.props; return( 我是一个类组件{name}---{age} ); } } 默认值

可以通过 defaultProps 设置默认值

// 父组件 function Component1(){ // 创建一个ref const porps = {name: 'ccc',age:18}; const a = {h: 'ccc'}; return ( {/* 如果是非字符串 就要用大括号*/} ); } // 子组件 function User(props){ return( 我是user组件 {props.name}---{props.age} ); } 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 ( ); } // 子组件 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( 我是一个类组件{this.state.name1}---{age} 点我加一{this.state.num} ); } } 修改 props

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

// 子组件 function User(props){ props.name = 'ttt'; return( 我是user组件 {props.name}---{props.age} ); } // 第三行报错

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

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

// 父组件 function Component1(){ const userRef = React.createRef(); const porps = {name: 'ccc',age:18}; return ( ); } // 子组件 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( 我是一个类组件{this.state.name1}---{age} 点我加一{this.state.num} ); } } 事件监听 this 绑定

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

下面我来介绍其他三种

直接在 jsx 元素上进行绑定(不推荐) // 父组件 function Component1(){ const userRef = React.createRef(); const porps = {name: 'ccc',age:18}; return ( ); } // 子组件 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( 我是一个类组件{this.state.name1}---{age} 点我加一{this.state.num} ); } }

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

箭头函数(推荐)

使用了 ES6 的类字段

// 父组件 function Component1(){ const userRef = React.createRef(); const porps = {name: 'ccc',age:18}; return ( ); } // 子组件 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( 我是一个类组件{this.state.name1}---{age} 点我加一{this.state.num} ); } }

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

直接在 jsx 上使用箭头函数(不推荐) // 父组件 function Component1(){ const userRef = React.createRef(); const porps = {name: 'ccc',age:18}; return ( ); } // 子组件 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( 我是一个类组件{this.state.name1}---{age} { this.setState(state =>({ num: ++state.num, })); }}>点我加一{this.state.num} ); } }

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



【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3