组件通信
在 ts 下的 react 组件通信, 需要给每个组件创建两个 interface 用于 ts 校验
父子通信
- 父组件绑定数据在子组件上
- 子组件通过 this.props 来接收数据
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30
| import React, { Component } from "react"; import Hello from "./components/Hello";
interface P { }
interface S { money: number; }
export default class App extends Component<P, S> { constructor(props: P) { super(props); this.state = { money: 2000, }; } render() { const { money } = this.state; return ( <div> <Hello money={money} /> </div> ); } }
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| import React, { Component } from "react";
interface P { money: number; }
interface S {}
export default class Hello extends Component<P, S> { render() { return ( <div> {this.props.money} {} </div> ); } }
|
子父通信
- 父亲传递一个方法给子组件
- 子组件调用这个方法并传参
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39
|
import React, { Component } from "react"; import Hello from "./components/Hello";
interface P {}
interface S { xjk: number; }
export default class App extends Component<P, S> { constructor(props: P) { super(props); this.state = { xjk: 2000, }; }
setXjk = (val: number) => { this.setState({ xjk: this.state.xjk + val, }); }; render() { const { xjk } = this.state; return ( <div> <Hello setXjk={this.setXjk} /> {xjk} </div> ); } }
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32
| import React, { Component } from "react";
interface P { setXjk: (val: number) => void; }
interface S { hongBao: number; }
export default class Hello extends Component<P, S> { constructor(props: P) { super(props); this.state = { hongBao: 888, }; } count = 1; sendHongBao = () => { if (this.count > 1) return; this.props.setXjk(this.state.hongBao); this.count++; }; render() { return ( <div> <button onClick={this.sendHongBao}>按钮</button> </div> ); } }
|
非父子间通信
- 通过 ref 绑定获取 brother 组件中的 setCryFlag
- 绑定这个方法给 sister
- 形成非父子间通信
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
| import React, { Component } from "react"; import Brother from "./components/Brother"; import Sister from "./components/Sister";
interface P {}
interface S {}
export default class App extends Component<P, S> { brother: any = {};
kick = () => { this.brother.setFlag(); }; render() { return ( <div> <Sister kick={this.kick} /> <Brother ref={(el) => (this.brother = el)} /> </div> ); } }
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27
| import React, { Component } from "react";
interface P {}
interface S { flag: boolean; }
export default class Brother extends Component<P, S> { constructor(props: P) { super(props); this.state = { flag: false, }; }
setFlag = () => { this.setState({ flag: !this.state.flag, }); }; render() { const { flag } = this.state; return <div>{flag && "哭"}</div>; } }
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| import React, { Component } from "react"; interface P { kick: () => void; } interface S {}
export default class Sister extends Component<P, S> { render() { return ( <div> <button onClick={this.props.kick}>按钮</button> </div> ); } }
|
跨组件通信
- 创建上下文对象
- 用 ctx.Provider 标签包裹 value 放数据
- 子孙组件通过 contextType 来接收 ctx 这个上下文对象
- 需要的子组件通过 this.context 直接使用
创建 context 文件夹并在里面放 index.ts
1 2 3 4 5
| import React, { createContext } from "react"; const ctx: React.Context<number> = createContext(0);
export default ctx;
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31
| import React, { Component } from "react"; import Father from "./components/Father"; import ctx from "./context";
interface P {}
interface S { money: number; }
export default class App extends Component<P, S> { constructor(props: P) { super(props); this.state = { money: 200000, }; } render() { const { money } = this.state; return ( <div> <ctx.Provider value={money}> {" "} <Father /> </ctx.Provider> </div> ); } }
|
1 2 3 4 5 6 7 8 9 10 11 12 13
| import React, { Component } from "react"; import Son from "./Son";
export default class Father extends Component { render() { return ( <div> <Son /> </div> ); } }
|
1 2 3 4 5 6 7 8 9 10 11 12 13
| import React, { Component } from "react"; import GrandSon from "./GrandSon";
export default class Son extends Component { render() { return ( <div> <GrandSon /> </div> ); } }
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| import React, { Component } from "react"; import ctx from "../context";
export default class GrandSon extends Component { static contextType = ctx; render() { return ( <div> {this.context} {} </div> ); } }
|