React 传值 通信传递

目录:

在开发中,避免代码过于繁琐.特将模块分离,通过一个个组件合在一起.

在组件与组件之间使用组件通信.

为了传递和共享某些数据

父子 兄弟 跨件相传

1.父传子

1.定义数据.

 state = {
    salary: 11.46,
}

2.在子标签上绑定数据

 <Fuzi salary={this.state.salary}></Fuzi>

3.子组件使用.

<div>工资:{this.props.salary}</div>

完整代码

import React, { Component } from 'react'
import Fuzi from './fuzi'

export default class Fu extends React.Component {
  state = {
    salary: 11.46,
  }
  render () {
    return (
      <>
        <h1>父:员工平均工资</h1>
        <hr />   
        <Fuzi salary={this.state.salary}></Fuzi>
      </>
    )
  }
}
----------------------------------------------------------------

import React, { Component } from 'react'


// 方式1 类组件接收.  this.props
export default class Fuzi extends React.Component {
  // constructor(props) {
  //   // 把继承过来的数据挂载到this实例上面.
  //   // 否则无法访问this
  //   super(props)
  //   console.log(this.props);
  // }
  constructor(...args) {
    super(...args)
    console.log(this.props);
  }
  render () {
    const { salary, age, bBar, iNum, changeAng, obj, jsxEle } = this.props
    return (
      <>
        <div>当前是子组件信息</div>
        <div>工资:{salary}</div>
        <div>年龄:{age}</div>
        <div>类型:{typeof bBar}</div>
        <div>数字:{iNum}</div>
        <div onClick={changeAng}>函数</div>
        <div>对象:{obj.age}</div>
        <div>标签:{jsxEle}</div>
      </>
    )
  }
}


// 方式2 函数组件接收. props 
// const Fuzi = (props) => {
//   return (
//     <>
//       <div>当前是子组件信息</div>
//       <div>工资:{props.salary}</div>
//     </>
//   )
// }

// export default Fuzi

2.子传父

某种意义上来说.子传父也叫父传子

1.在父定义函数.绑定在子标签上

2.子定义事件.和函数.

3.修改对象的属性,然后通过this.props找到父的函数.传递对应的参数.

完整代码


import React, { Component } from 'react'
import Child from '../Child'
import './index.css'

class Parent extends Component {
  state = {
    list: [
      {
        id: 1,
        name: '超级好吃的棒棒糖',
        price: 18.8,
        info: '开业大酬宾,全场7折',
      },
      {
        id: 2,
        name: '超级好吃的大鸡腿',
        price: 34.2,
        info: '开业大酬宾,全场6折',
      },
      {
        id: 3,
        name: '超级无敌的冰激凌',
        price: 14.2,
        info: '开业大酬宾,全场5折',
      },
    ],
  }
  // 方法1 子传父砍一刀
  // changAngen = (id, price) => {
  //   this.setState({
  //     list: this.state.list.map((item) => {
  //       if (item.id === id) {
  //         let p = price.toFixed(2)
  //         if (p <= 0) {
  //           p = 0
  //         }
  //         return {
  //           ...item,
  //           price: p - 0
  //         }
  //       } else {
  //         return item
  //       }
  //     })
  //   })
  // }

  // 方法2 子传父砍一刀
  changAngen = (id, price) => {
    this.setState({
      list: this.state.list.map((item) => {
        if (item.id === id) {
          let p = (item.price - price).toFixed(2)
          if (p <= 0) {
            p = 0
          }
          return {
            ...item,
            price: p + 0
          }
        }
        else {
          return item
        }
      })
    })
  }
  render () {
    const { list } = this.state
    return (
      <div className='parent'>
        {list.map((item) => (
          // <Child
          //   key={item.id}
          //   name={item.name}
          //   price={item.price}
          //   info={item.info}
          // ></Child>

          // 简化  类似vue 中的v-bind
          <Child
            key={item.id}
            {...item}
            changAngen={this.changAngen}
          >
          </Child>
        ))}
      </div>
    )
  }
}

export default Parent

----------------------------------------------------------------------------------------
import React, { Component } from 'react'
import './index.css'

// 方法1 子传父砍一刀
// export default class Child extends Component {
//   constructor(props) {
//     super(props)
//   }
//   render () {
//     const { name, price, info, id, changAngen } = this.props
//     return (
//       <div className='child'>
//         <h3 className='title'>标题:{name}</h3>
//         <p className='price'>价格:{price}</p>
//         <p className='product'>{info}</p>
//         <button onClick={() => changAngen(id, price - 2)}>砍一刀</button>
//       </div>
//     )
//   }
// }

// 方法2 子传父砍一刀
export default class Child extends Component {

  changAngen = () => {
    const price = Math.floor(Math.random() * 3) + 1
    this.props.changAngen(this.props.id, price)
  }
  render () {
    const { name, price, info } = this.props
    return (
      <div className='child'>
        <h3 className='title'>标题:{name}</h3>
        <p className='price'>价格:{price}</p>
        <p className='product'>{info}</p>
        <button onClick={this.changAngen}>砍一刀</button>
      </div>
    )
  }
}

3.兄弟传值

1.将无关联的组件一起绑定在同一个父级身上.

2.在公共的父级身上定义属性和方法

3.然后在对应的子组件标签绑定属性和方法

完整代码

import React, { Component } from 'react'
import Child from '../Child'
import './index.css'

import A from '../count/A'
import B from '../count/B'

class Parent extends Component {
  state = {
    num: 0,
    list: [
      {
        id: 1,
        name: '超级好吃的棒棒糖',
        price: 18.8,
        info: '开业大酬宾,全场7折',
      },
      {
        id: 2,
        name: '超级好吃的大鸡腿',
        price: 34.2,
        info: '开业大酬宾,全场6折',
      },
      {
        id: 3,
        name: '超级无敌的冰激凌',
        price: 14.2,
        info: '开业大酬宾,全场5折',
      },
    ],
  }
  // 方法 1子传父砍一刀
  // changAngen = (id, price) => {
  //   this.setState({
  //     list: this.state.list.map((item) => {
  //       if (item.id === id) {
  //         let p = price.toFixed(2)
  //         if (p <= 0) {
  //           p = 0
  //         }
  //         return {
  //           ...item,
  //           price: p - 0
  //         }
  //       } else {
  //         return item
  //       }
  //     })
  //   })
  // }

  // 方法2
  changAngen = (id, price) => {
    this.setState({
      list: this.state.list.map((item) => {
        if (item.id === id) {
          let p = (item.price - price).toFixed(2)
          if (p <= 0) {
            p = 0
          }
          return {
            ...item,
            price: p + 0
          }
        }
        else {
          return item
        }
      })
    })
  }

  // 兄弟传值
  // 1.定义两个无关联的js
  // 2.在公共的父组件中分别绑定数据
  // 3.通过父传子的方式.改变兄弟的数据.
  hanAdd = (a) => {
    this.setState({
      num: this.state.num + a
    })
  }
  render () {
    const { list } = this.state
    return (
      <div className='parent'>
        {list.map((item) => (
          // <Child
          //   key={item.id}
          //   name={item.name}
          //   price={item.price}
          //   info={item.info}
          // ></Child>

          // 简化  类似vue 中的v-bind
          <Child
            key={item.id}
            {...item}
            changAngen={this.changAngen}
          >
          </Child>
        ))}
        <hr />
        <A hanAdd={this.hanAdd} />
        <hr />
        <B num={this.state.num} />
      </div>
    )
  }
}

export default Parent

------------------------------------------------------------------------------------

import React, { Component } from 'react'
import './index.css'

// 方法1 子传父砍一刀
// export default class Child extends Component {
//   constructor(props) {
//     super(props)
//   }
//   render () {
//     const { name, price, info, id, changAngen } = this.props
//     return (
//       <div className='child'>
//         <h3 className='title'>标题:{name}</h3>
//         <p className='price'>价格:{price}</p>
//         <p className='product'>{info}</p>
//         <button onClick={() => changAngen(id, price - 2)}>砍一刀</button>
//       </div>
//     )
//   }
// }

// 方法2
export default class Child extends Component {
  constructor(props) {
    super(props)
  }
  changAngen = () => {
    const price = Math.floor(Math.random() * 3) + 1
    this.props.changAngen(this.props.id, price)
  }
  render () {
    const { name, price, info } = this.props
    return (
      <div className='child'>
        <h3 className='title'>标题:{name}</h3>
        <p className='price'>价格:{price}</p>
        <p className='product'>{info}</p>
        <button onClick={this.changAngen}>砍一刀</button>
      </div>
    )
  }
}

4.祖父传值

  1. 祖先组件通过 React.crateContext() 创建 Context 并导出。

  2. 祖先组件通过 <Context.Provider> 配合 value 属性提供数据。

  3. 后代组件通过 <Context.Consumer> 配合函数获取数据。

  4. 优化:提取 React.crateContext() 到单独的文件里面。

完整代码

index.js

import React, { Component, createContext } from 'react'
import ReactDOM from 'react-dom'
import App from './App'
export const context = createContext()

// 祖先级默认导出携带默认数据
// export const Context = React.createContext({
//   age: '18'
// })

const el = (
  <>
    <App />
  </>
)


ReactDOM.render(el, document.querySelector('#root'))

 App.js

import React, { Component, } from 'react'
import A from './A'
import { context } from './index'
export default class App extends React.Component {
  render () {
    return (
      <>
        <context.Provider
          value={
   
   {
            age: 18
          }}>
          <div>祖先</div>
          <hr />
          <A />
        </context.Provider>
      </>
    )
  }
}

A.js

import React, { Component } from 'react'
import B from './B'
export default class A extends React.Component {
  render () {
    return (
      <>
        <div>A</div>
        <hr />
        <B />
      </>
    )
  }
}

B.js

import React, { Component } from 'react'
import { context } from './index'

export default class B extends React.Component {
  render () {
    return (
      <>
        <context.Consumer>
          {value => {
            return (
              <div>B{value.age}</div>
            )
          }}
        </context.Consumer>
      </>
    )
  }
}

Guess you like

Origin blog.csdn.net/wangyangzxc123/article/details/121801296