目录 组件间传值 props ref 状态提升 跨组件通信 组件间传值 props 父传子:通过自定义属性向子组件传值,值可以是任何类型 子传父:通过父组件把方法传给子组件,子组件调用传过去的
目录
- 组件间传值
- props
- ref
- 状态提升
- 跨组件通信
组件间传值
props
父传子:通过自定义属性向子组件传值,值可以是任何类型
子传父:通过父组件把方法传给子组件,子组件调用传过去的方法完成传值
注:
1.定义方法时尽可能的去使用箭头函数定义
2.调用时,尽可能的写小括号
父组件中的方法 // 成员方法 箭头函数来定义,这样就没有this指向问题 setNum = (n = 1) => this.setState(state => ({ num: state.num + n })) <Child num={num} setNum={this.setNum} /> 子组件中 <button onClick={() => setNum(2)}>+++++</button> 子去修改父传过来的数据,props它是单向数据流,子不能直接去修改
ref
- 父子间传值:通过ref引用对象完成对于【类组件】之间通信
this.childRef.current
得到当前Child组件的实例对象
childRef = createRef() <Child ref={this.childRef} /> ++++++++++++++++++++++++++++++++ this.setState({ title: this.childRef.current.state.title }) this.childRef.current.setState({ title: this.state.msg }) this.childRef.current.setTitle(this.state.msg)
状态提升
此方案用来解决兄弟组件间的传值问题,就是把共用的状态信息提升到父组件状态中。
import React, { Component } from 'react' class Child1 extends Component { render() { let { setMsg } = this.props return ( <div> <input type="text" onChange={e => setMsg(e.target.value)} /> </div> ) } } class Child2 extends Component { render() { let { msg } = this.props return ( <div> <h3>{msg}</h3> </div> ) } } class App extends Component { state = { msg: '' } setMsg = msg => this.setState({ msg }) render() { return ( <div> <h1>{this.state.msg}</h1> <Child1 setMsg={this.setMsg} /> <Child2 msg={this.state.msg} /> </div> ) } } export default App
或者:
class App extends Component { state = { msg: '', setMsg: msg => this.setState({ msg }) } render() { let { msg, setMsg } = this.state return ( <div> <h1>{msg}</h1> {/* <Child1 setMsg={setMsg} /> */} {/* <Child2 msg={msg} /> */} <Child1 {...this.state} /> <Child2 {...this.state} /> </div> ) } }
跨组件通信
context实现在跨组件通信,一般用于自定义组件
- context一个项目中可以有N个,但是一般情况下我们使用它,都是把它放在App组件中,一个项目一个。
- 因为Context会让组件变得不纯粹,因为依赖了全局变量。所以这决定了Context一般不会大规模的使用。所以一般在一个组件中使用一个Context就好。
- context实现在跨组件通信,一般用于自定义组件所用
- context绑定消费是一定是一个对象
import { createConext } from 'react' const ctx = createContext() const { Provider, Consumer } = ctx export { ctx as default, Provider, Consumer }
- Provider,Consumer 都是组件
- Provider 生产数据的组件
- Consumer 消费的组件
导入
在App组件中生产数据,这样下面的子孙组件就可以调用此context
对象来消费数据,value属性就是生产的数据源
app.jsx
import Child from './pages/Child' import { Provider } from './context/appContext' class App extends Component { state = { name: "张三", setName: (name) => this.setState({ name }), }; ======================================================= render() { return ( <div> {/* value属性就是生产的数据源 */} <Provider value={this.state}> <Child /> </Provider> </div> ); } }
child.jsx文件
两种方法来消费(获取)数据
类组件中context还可以换一个方案来消费,定义好后,就可以通过成员属性 this.context来获取数据
方式1:通过组件消费:
由于Consumer的特性,里面的代码必须是这个函数的返回值。
// 假设现在当前组件是App组件下面的很深的子孙组件 import ctx, { Consumer } from '../../context/appContext' ..... <Consumer>{state => <h3>{state.name}</h3>}</Consumer>
方式2:通过绑定静成属性来消费
首先用static 来声明contextType
static contextType = ctx
这样在运行是就会获得一个新的属性,我们来接收它,这样consumer就可以完全不再使用了。
const battery = this.context
// 假设现在当前组件是App组件下面的很深的子孙组件 import ctx, { Consumer } from '../../context/appContext' static contextType = ctx const battery = this.context //就可以通过成员属性 this.context来获取数据 ..... <h3>{this.context.name}</h3> <h3>{battery.name}</h3>
到此这篇关于React组件间传值及跨组件通信详解的文章就介绍到这了,更多相关React组件间传值内容请搜索易盾网络以前的文章或继续浏览下面的相关文章希望大家以后多多支持易盾网络!