目录
父传子
1. 父组件提供要传递的数据 - `state`
2. 给子组件标签`添加属性`值为 state中的数据
3. 子组件中通过 `props` 接收父组件中传过来的数据
4. - 类组件可以使用this.props获取props对象
- 函数式组件直接通过参数获取props对象
父组件: 初始化状态,子组件标签写 msg= {}
子组件:函数拿到msg: 参数props拿
类拿到msg:this.props拿
扩展: {...info} 把info对象解构 一起传递给子组件
import React from 'react'
import styles from './App.module.css'
import { FSon } from './FSon'
import { CSon } from './CSon'
export class Header extends React.Component {
//初始化状态
state = {
message: '回来吃饭',
info: {
id: 1,
name: 'hali',
},
}
render() {
const { message, info } = this.state
return (
<div className={styles.one}>
<div>父</div>
<FSon msg={message} {...info} />
<CSon msg={message} {...info} />
</div>
)
}
}
子组件
import React from 'react'
import styles from './App.module.css'
// 函数式子组件
export const FSon = (props: any) => {
const { msg, id, name } = props
console.log('函数式子组件', props)
return (
<div className={styles.two}>
<div>函数子组件:</div>
{msg}
<div>
{id}
{name}
</div>
</div>
)
}
import React from 'react'
import styles from './App.module.css'
// 类子组件
export class CSon extends React.Component<any> {
render() {
console.log('类子组件', this)
const { msg, id, name } = this.props
return (
<div className={styles.three}>
<div>类子组件:</div>
{msg}
<div>
{id}
{name}
</div>
</div>
)
}
}
注意:
1. props是只读对象(readonly)
根据单项数据流的要求,子组件只能读取props中的数据,不能进行修改
2. props可以传递任意数据
数字、字符串、布尔值、数组、对象、函数、JSX
子传父
父组件给子组件传递回调函数,子组件调用
父组件定义函数,通过props:changeMsg={this.changeMessage}传递函数给子组件
import React from 'react'
import styles from './App.module.css'
import { FSon } from './FSon'
export class Header extends React.Component {
//初始化状态
state = {
message: '回来吃饭',
}
// 提供回调函数
changeMessage = (newMsg: any) => {
console.log('子组件传过来的数据:', newMsg)
this.setState({
message: newMsg,
})
}
render() {
const { message } = this.state
return (
<div className={styles.one}>
<div>父</div>
<FSon msg={message} changeMsg={this.changeMessage} />
</div>
)
}
}
子组件通过props拿到父传过来的函数,点击触发父亲的函数并且传递数据给父亲,重新设置message的值
import React from 'react'
import styles from './App.module.css'
// 函数式子组件
export const FSon = (props: any) => {
const { msg, changeMsg } = props
const handleClick = () => {
changeMsg('我就不回去')
}
return (
<div className={styles.two}>
<div>函数子组件:</div>
{msg}
<button onClick={handleClick}>change</button>
</div>
)
}
兄弟组件
可以先 子传给父 ,再把数据传递给 另外一个子,可以结合上面的俩种方法
跨组件通信Context
第一种写法
使用步骤:
1.创建Context对象 导出 Provider 和 Consumer对象
2. 使用Provider包裹 最外层 组件提供数据
3.需要用到数据的 里层 组件使用Consumer包裹获取数据
import React, { createContext, ReactNode } from 'react'
import styles from './App.module.css'
// 1. 创建Context对象,并指定默认值的类型
const { Provider, Consumer } = createContext<string>('default value')
// 3. 消费数据
function ComC() {
return (
<div className={styles.three}>
<Consumer>{(value) => <div>{value}</div>}</Consumer>
</div>
)
}
function ComA() {
return (
<div className={styles.two}>
<ComC />
</div>
)
}
// 2. 提供数据
export class Header extends React.Component {
state = {
message: '孙子',
}
render() {
console.log('父组件', this)
const { message } = this.state
return (
<Provider value={message}>
<div className={styles.one}>
<ComA />
</div>
</Provider>
)
}
}
第二种写法
使用步骤:
1.创建Context对象
import { createContext } from "react";
// 1. 创建Context对象,自己命名
export default createContext<any>({})
2.Context.Provider包裹后代组件 ,value提供数据
import React from 'react'
import styles from './App.module.css'
import { ComA } from './ComA'
import Context from './context'
// 2. Context.Provider包裹后代组件 ,value提供数据
// <Context.Provider value = {message}>
// <ComA />
//</Context.Provider>
export class Header extends React.Component {
state = {
message: '孙子',
}
render() {
console.log('父组件', this)
const { message } = this.state
return (
<div className={styles.one}>
<div>父组件:{message}</div>
<Context.Provider value = {message}>
<ComA />
</Context.Provider>
</div>
)
}
}
3.要使用数据就 const xxx = useContext(Context)拿到value值
import React, { useContext } from 'react'
import styles from './App.module.css'
import Context from './context'
// 3. 要使用数据就 const a = useContext(Context)拿到value值
export function ComC(props: any) {
console.log('ComC',props);
const messageOfC = useContext(Context)
return (
<div className={styles.three}>
<div>孙子:{messageOfC}</div>
</div>
)
}