一. 父传子组件
- 在父组件通过属性传递内容,
- 子组件通过
props拿到内容
举例:
父组件:
export class Main extends Component {
constructor() {
super()
this.state = {
banners: [],
productList: []
}
}
componentDidMount() {
axios.get("http://").then(res => {
const banners = res.data.data.banner.list
const recommend = res.data.data.recommend.list
this.setState({
banners,
productList: recommend
})
})
}
render() {
const { banners, productList } = this.state
return (
<div className='main'>
<div>Main</div>
<MainBanner banners={banners} title="轮播图"/>
<MainBanner/>
<MainProductList productList={productList}/>
</div>
)
}
}
子组件:
export class MainProductList extends Component {
render() {
const { productList } = this.props
return (
<div>
<h2>商品列表</h2>
<ul>
{
productList.map(item => {
return <li key={item.acm}>{item.title}</li>
})
}
</ul>
</div>
)
}
}
export default MainProductList
如果子组件里还有本身设置的state数据,则需在构造函数中获取props,子组件也可以设置传入的类型验证和默认值。
export class MainBanner extends Component {
// static defaultProps = {
// banners: [],
// title: "默认标题"
// }
constructor(props) {
super(props)
this.state = {}
}
render() {
// console.log(this.props)
const { title, banners } = this.props
return (
<div className='banner'>
<h2>封装一个轮播图: {title}</h2>
<ul>
{
banners.map(item => {
return <li key={item.acm}>{item.title}</li>
})
}
</ul>
</div>
)
}
}
// MainBanner传入的props类型进行验证
MainBanner.propTypes = {
banners: PropTypes.array,
title: PropTypes.string
}
// MainBanner传入的props的默认值
MainBanner.defaultProps = {
banners: [],
title: "默认标题"
}
export default MainBanner
二. 子传父组件
- 父组件传递函数
- 子组件调用父组件传递的函数,传递参数给父组件
- 父组件获取参数调用回调函数
举例:
父组件:
export class App extends Component {
constructor() {
super()
this.state = {
counter: 100
}
}
changeCounter(count) {
this.setState({ counter: this.state.counter + count })
}
render() {
const { counter } = this.state
return (
<div>
<h2>当前计数: {counter}</h2>
<AddCounter addClick={(count) => this.changeCounter(count)}/>
</div>
)
}
}
子组件:
export class AddCounter extends Component {
addCount(count) {
this.props.addClick(count)
}
render() {
return (
<div>
<button onClick={e => this.addCount(1)}>+1</button>
<button onClick={e => this.addCount(5)}>+5</button>
<button onClick={e => this.addCount(10)}>+10</button>
</div>
)
}
}
// AddCounter.propTypes = {
// addClick: PropTypes.func
// }
export default AddCounter
三. 非父组件通信
1. 使用context
- 创建context
- 在要使用的组件,一般是根组件导入context
- 使用<context.Provider>包裹后代组件
- 在要使用的后代组件引入context
- xxxx.contextType = context
- 在render方法中可以通过this.context拿到传递过来的值
// 1.第一步操作 创建一个Context
const ThemeContext = React.createContext({ color: "blue", size: 10 }) //可设置默认值
export default ThemeContext
根组件App :
import React, { Component } from 'react'
import ThemeContext from "./context/theme-context"
export class App extends Component {
constructor() {
super()
this.state = {
info: { name: "kobe", age: 30 }
}
}
render() {
const { info } = this.state
return (
<div>
<h2>App</h2>
{/* 1.给Home传递数据的方式 */}
{/* <Home name="why" age={18}/>
<Home name={info.name} age={info.age}/>
<Home {...info}/> */}
{/* 2.普通的Home */}
{/* 第二步操作: 通过ThemeContext中Provider中value属性为后代提供数据 */}
<UserContext.Provider value={{nickname: "kobe", age: 30}}>
<ThemeContext.Provider value={{color: "red", size: "30"}}>
<Home {...info}/>
</ThemeContext.Provider>
</UserContext.Provider>
<Profile/>
</div>
)
}
}
export default App
Home组件:
export class Home extends Component {
render() {
const { name, age } = this.props
return (
<div>
<h2>Home: {name}-{age}</h2>
<HomeInfo/>
<HomeBanner/>
</div>
)
}
}
export default Home
Home下子组件:
类组件可以外部包裹UserContext.Consumer获取数据,也可以xxxx.contextType = context 获取
import ThemeContext from './context/theme-context'
import UserContext from './context/user-context'
export class HomeInfo extends Component {
render() {
// 4.第四步操作: 获取数据, 并且使用数据
console.log(this.context)
return (
<div>
<h2>HomeInfo: {this.context.color}</h2>
<UserContext.Consumer>
{
value => {
return <h2>Info User: {value.nickname}</h2>
}
}
</UserContext.Consumer>
</div>
)
}
}
// 3.第三步操作: 设置组件的contextType为某一个Context
HomeInfo.contextType = ThemeContext
export default HomeInfo
函数式组件中使用Context共享的数据,必须外部包裹ThemeContext.Consumer
import ThemeContext from "./context/theme-context"
function HomeBanner() {
return <div>
<ThemeContext.Consumer>
{
value => {
return <h2> Banner theme:{value.color}</h2>
}
}
</ThemeContext.Consumer>
</div>
}
export default HomeBanner