React传值
数据传值大概无非是这几种情况。
1.父传子
2.子传夫
3.跨层级组件传值
4.路由传值(什么情况都可以用~但是涉及一些长的或者隐私的不建议用)
我这个人对传值这块真的有时候迷迷糊糊的,所以这次刚好复习的时候整理一下传值。
父传子
这个是最简单也是最常用的传值了。
前提条件就是父组件要引用子组件!
通常是通过props和ref传值和方法
props
父组件:
import './App.css';
import Chid from './Chid.jsx'
import React, { Component } from 'react'
export default class extends Component {
constructor(props) {
super(props)
}
fun() {
//这里是传的方法
console.log('this is function')
}
render() {
return (
<div className="App">
<Chid fun={this.fun} aa='value' />
</div>
)
}
}
子组件:
import React, { Component } from 'react'
export default class Chid extends Component {
constructor(props) {
super(props)
//通过props传递的function 执行fun()
this.props.fun.bind(this)()
}
render() {
return (
<div>
{this.props.aa}
</div>
)
}
}
通过ref传值
父组件可以通过ref选择到子组件的function,如果需要子组件的值则用return
父组件:
import './App.css';
import Chid from './Chid.jsx'
import React, { Component } from 'react'
export default class extends Component {
constructor(props) {
super(props)
}
componentDidMount() {
let x = this.foo.myFun() //输出:我是被传的function
console.log(x)
}
render() {
return (
<div className="App">
<Chid ref={(foo) => { this.foo = foo }} />
</div>
)
}
}
子组件:
import React, { Component } from 'react'
export default class Chid extends Component {
myFun() {
console.log('我是被传的function')
}
render() {
return (
<div>
{this.props.aa}
</div>
)
}
}
子传父
父组件通过props向子组件传入一个方法,子组件在通过调用该方法,将数据以参数的形式传给父组件,父组件通过该方法使用数据。
父组件:
import './App.css';
import Chid from './Chid.jsx'
import React, { Component } from 'react'
export default class extends Component {
constructor(props) {
super(props)
}
getData = (e) => {
console.log(e)
}
render() {
return (
<div className="App">
<Chid getData={this.getData} />
</div>
)
}
}
子组件:
import React, { Component } from 'react'
export default class Chid extends Component {
constructor(props) {
super(props)
this.state = {
chidData: [1, 2, 3, 4]
}
}
render() {
const { chidData } = this.state
return (
<div>
<button onClick={() => { this.props.getData(chidData) }}>
{chidData}
</button>
</div>
)
}
}
利用props callback通信,父组件传递一个 callback 到子组件,当事件触发时将参数放置到 callback 带回给父组件。
父组件:
import './App.css';
import Chid from './Chid.jsx'
import React, { Component } from 'react'
export default class extends Component {
constructor(props) {
super(props)
}
callback = (value) => {
//得到子组件传值value
console.log(value)
}
render() {
return (
<div className="App">
<Chid callback={this.callback} />
</div>
)
}
}
子组件:
import React, { Component } from 'react'
export default class Chid extends Component {
constructor(props) {
super(props)
this.handleChange = this.handleChange.bind(this)
}
handleChange = (e) => {
// 在此处将参数带回
this.props.callback(e.target.value)
}
render() {
return (
<div>
<input type='text' onChange={this.handleChange} />
</div>
)
}
}
跨层级组件之间
使用 Context作为中间载体传值。避免了在每一个层级手动的传递 props 属性,适合于多层级的时候使用
官方文档
首先:新建 Context.js
const { Consumer, Provider } = React.createContext(null)
//创建 context 并暴露Consumer(使用者)和Provide(提供者)
export { Consumer, Provider }
父元素(提供者)使用:
import './App.css';
import Chid from './Chid.jsx'
import React, { Component } from 'react'
//引入 取名 Provider
import { Provider } from './context'
export default class extends Component {
constructor(props) {
super(props)
}
render() {
return (
<div className="App">
<Provider value={'this.state.info'}>
<div>
<p>{'this.state.info'}</p>
<Chid />
</div>
</Provider>
</div>
)
}
}
子组件:
import React, { Component } from 'react'
import { Consumer } from './context'
import GrandSon from './Grandson'
export default class Chid extends Component {
constructor(props) {
super(props)
}
render() {
return (
<Consumer>
{(info) => (
// 通过Consumer直接获取父组件的值
<div>
<p>父组件的值:{info}</p>
<GrandSon />
</div>
)}
</Consumer>
)
}
}
孙子组件:
import React from 'react'
import { Consumer } from './context'
class GrandSon extends React.Component {
//
constructor(props) {
super(props)
}
// 如果要用值的话,先使用 static 这个类属性来初始化 contextType,然后通过this.context获取值
static contextType = Consumer;
componentDidMount() {
//this.context是Consumer info的值,输出和显示一致。
console.log(this.context)
}
render() {
return (
<Consumer>
{(info) => (
// 通过 Consumer 中可以直接获取组父组件的值
<div>
<p>组父组件的值:{info}</p>
</div>
)}
</Consumer>
)
}
}
export default GrandSon
路由传值
最经典的就是使用params传值 需安装react-router-dom
形式:/:xx (xx就是要传值的参数)
怎么用呢?来看以下几步。
首先
路由配置:
<Route exact path="/index/:name" component={Index} />
//跳转地址就是/index/xx
1.js跳转:
this.props.history.push('/index/mika')
2.标签跳转:
引入Link标签 import { Link } from 'react-router-dom'
使用Link标签跳转 <Link to="/index/mika">this is link</Link>
跳转页面接收值:this.props.match.params.name
其中name就是传的参数值,自己定义了什么就叫什么名字。
还有一种query传参
1.js跳转:
this.props.history.push({
pathname: '/index',
query: { name: 'mika', age: 18 }
})
在要跳转的组件上绑定onClick就可以使用。query为一个对象,携带的是需要传的参数。
不需要提前引入,也不需要路由设置,正常配置就可以。
跳转页面接收值:this.props.location.query
简单的说一下2个传参的区别:
1.params传递显示参数,query传递不显示参数,query相对于params来说较安全一点
2.params传值页面刷新数据还在,而query传值页面刷新数据会消失。
3.params传值只能传一个,query可以传多个对象。
那有没有数据传参不显示、刷新地址栏数据也不会小时的方法呢?有啊!
state 传参
传参的方法和query差不多,属性不一样。
不需要路由配置
1.js跳转:this.props.history.push({pathname:'/index',state:{name:'mima'}})
2.标签跳转 <Link to={{path:'/index',state:{name:'mika'}}}>XX</Link>
跳转页面接收值: this.props.location.state.name
以上暂时就这些了没包括一些传值的包,如果需要可以自己去了解