一、父传子
1. props传参
// 1. 类式组件
class ComC extends React.Component {
render() {
return (
{
/* 类式组件通过 `this.props.xx`获取参数 */}
<div>{
this.props.title}</div>
)
}
}
// 2.函数式组件
function ComF(props) {
return (
// 函数式组件,通过 函数入参 传递参数
<div>{
props.title}</div>
)
}
class App extends React.Component {
render (){
return (
<ComC title="这是类式组件"/>
<ComF title="这是函数式组件"/>
)
}
}
props说明
1. props是只读对象
(readOnly)
根据单向数据流的要求,子组件只能读取props的数据,不能修改。
2. props可以传递任意数据
数字、字符串、数组、对象、布尔、函数、jsx
function Son(props) {
cosnt {
list, obj, jsxObj} = props; //解构
return (
{
/*
<div>
{props.list.map(item => (
<p key="item">{item}</p>
))}
<p>{props.obj.name}</p>
{props.jsxObj}
</div>
*/}
{
/*支持解构*/}
<div>
{
this.props.list.map(item => (
<p key="item">{
item}</p>
))}
<p>{
this.props.obj.name}</p>
{
this.props.jsxObj}
</div>
)
}
class App extends React.Component {
state = {
list:[1,2,3],
obj:{
name: "李白",
age: 1200
} }
render (){
return (
<Son
list={
this.state.list}
obj={
this.state.obj}
jsxObj="<span>这是传递的jsx对象</span>"
/>
)
}
}
二、子传父
子组件调用父组件传递过来的函数,将要传递的数据作为实参传入该函数即可。
function Son(props){
const {
handler} = props;
return (
<button onClick={
() => handler('子组件传递给父组件的值')}></button>
)
}
class App extends React.Component {
handler = (text) => {
console.log(text);
}
render(){
return (
<Son handler={
handler} />
)
}
}
三、兄弟组件通信
核心思路:利用状态提升机制,通过共同的父组件 实现兄弟通信
步骤:
先把B中的数据通过 子传父 传给 App;
再把App 中的数据通过 父传子 传给 A
function SonA(props) {
return (
<div>this is {
props.sendAMsg}</div>
)
}
function SonB(props) {
const {
sendBMsg} = props;
return (
<div>B send to A <button onClick={
() => sendBMsg('来自B的数据')}>点击传值</button></div>
)
}
class App extends React.Component {
state = {
sendAMsg:""
}
sendBMsg = (val) =>{
this.setState({
sendAMsg: val
})
}
render(){
return (
<div>
<SonA sendAMsg={
this.state.sendAMsg} />
<SonB sendBMsg={
sendBMsg} />
)
}
}
四、跨组件通信 Context
实现步骤:
1. 类组件
1.创建 Context实例,导出 Provider、Consumer对象
const {Provider, Consumer} = createContext();
2.使用 Provider 包裹根组件,通过 value 提供数据
<Provider value={this.state.msg}>
{/*根组件*/}
</Provider>
3.使用Consumer 包裹使用数据的组件,获取数据
<Consumer>
{value => /* 基于context 的值进行渲染*/}
</Consumer>
实例:
import React, {
createContext} from "react";
// 组件 App -> A -> C
// App数据 -> C
// 1.导出 Provider、Consumer 两对象
const {
Provider, Consumer} = createContext();
function ComC() {
return (
<div>
this is ComC
{
/*3. 通过 Consumer 使用数据*/}
<Consumer>
{
value => (<p>{
value}</p>)}
</Consumer>
</div>
)
}
function ComA() {
return (
<div>
this is ComA
<ComC />
</div>
)
}
class App extends React.Component {
state = {
msg: "this is message"
}
render () {
return (
<Provider value={
this.state.msg}>
{
/*2.使用Provider 包裹根组件*/}
<div>
<ComA />
</div>
</Provider>
)
}
}
2. 函数组件
- 使用
createContext
创建 Context 对象 - 在顶层组件通过
Provider
提供数据 - 在底层组件通过
useContext
函数获取数据
代码示例:
import React, {
useState, createContext, useContext} from "react";
// 1. 通过createContext 构造 Context 对象
const Context = createContext();
function SonB() {
const count = useContext(Context);
return (
<div>
This is SonB, count is {
count}
</div>
)
}
function SonA() {
// 3.在底层组件中使用 useContext() 获取数据
const count = useContext(Context);
return (
<div>
This is SonA, count is {
count}
<SonB></SonB>
</div>
)
}
function App() {
const [count, setCount] = useState(10);
return (
<Context.Provider value={
count}>
{
/* 2.在顶层组件使用 Context.Provider 提供数据 */}
<div>
<button onClick={
() => setCount(100)}>change{
count}</button>
<SonA ></SonA>
</div>
</Context.Provider>
)
}
注意
1.如果Context 需要传递数据并且将来还需要再对数据做修改,底层组件也需要一起改变时,如上示例 写在app.js中
2. Context 如果要传递的数据 只需在整个应用初始化的时候传递一次,可以选择在最外层 index.js 中做数据提供
// index.js
ReactDOM.render(
<React.StrictMode>
<Context.Provider value="10">
<App />
</Context.Provider>
<React.StrictMode>
)
五、特殊的 Children
Children
表示该组件的子节点,只有组件有子节点,props中有该属性。
Children 可以是什么?
1.普通文本
2.普通标签
3.函数
4.jsx
import React from "react";
function Son(props) {
const {
children} = props;
children();
return (
<div>
this is Son.
{
/* <div>{children}</div> */}
</div>
)
}
class App extends React.Component {
render() {
return (
<>
{
/* <Son >this is Children.</Son>
<Son>{<p>this is P.</p>}</Son> */}
{
/* 传递函数 */}
<Son>{
() => console.log(1111)}</Son>
</>
)
}
}
export default App;