React组件间传值
勇敢*牛牛 人气:0组件间传值
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>
加载全部内容