目录:
在开发中,避免代码过于繁琐.特将模块分离,通过一个个组件合在一起.
在组件与组件之间使用组件通信.
为了传递和共享某些数据
父子 兄弟 跨件相传
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.祖父传值
-
祖先组件通过
React.crateContext()
创建 Context 并导出。 -
祖先组件通过
<Context.Provider>
配合 value 属性提供数据。 -
后代组件通过
<Context.Consumer>
配合函数获取数据。 -
优化:提取
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>
</>
)
}
}