React传值

2022-03-15  本文已影响0人  米卡卡米

数据传值大概无非是这几种情况。
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

以上暂时就这些了没包括一些传值的包,如果需要可以自己去了解

上一篇 下一篇

猜你喜欢

热点阅读