React 组件通信总结
父子通信
-
传递数据(父传子)与传递方法(子传父)
/* * @Author: HuangBingQuan [email protected] * @Date: 2022-11-21 16:02:17 * @LastEditors: HuangBingQuan [email protected] * @LastEditTime: 2022-11-21 16:48:31 * @FilePath: /react_test/src/02-advanced/01-子传父.js * @Description: 这是默认设置,请设置`customMade`, 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE */ import React, { Component } from 'react' class Navbar extends Component { render() { return ( <div style={{background: "red"}}> {/* <button onClick={()=> { let that = this.props.that; console.log(that.state.SidebarIsShow); that.setState({ SidebarIsShow: !that.state.SidebarIsShow }) }}>click</button> */} <button onClick={()=> { // 子通知父,让父的SidebarIsShow 取反 this.props.event() // 调用父组件传来的回调函数 }} > click </button> <span>NavBar</span> </div> ) } } class Sidebar extends Component { render() { return ( <div style={{background: "yellow", width: "200px"}}> <ul> <li>111111</li> <li>111111</li> <li>111111</li> <li>111111</li> <li>111111</li> <li>111111</li> </ul> </div> ) } } export default class App extends Component { state = { SidebarIsShow: false } render() { return ( <div> {/* <Navbar that={this}></Navbar> */} {/* */} <Navbar event={()=> { this.setState({ SidebarIsShow: !this.state.SidebarIsShow }) }}></Navbar> {/* <Sidebar></Sidebar> */} { this.state.SidebarIsShow && <Sidebar></Sidebar> } </div> ) } }
-
ref标记(父组件拿到子组件的引用,从而调用子组件的方法)
/* * @Author: HuangBingQuan [email protected] * @Date: 2022-11-21 21:38:26 * @LastEditors: HuangBingQuan [email protected] * @LastEditTime: 2022-11-22 16:51:06 * @FilePath: /react_test/src/02-advanced/04-父子通信版-表单域组件.js * @Description: 这是默认设置,请设置`customMade`, 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE */ import React, { Component } from 'react' class Filed extends Component { state = { val: "" } render() { return ( <div style={{background: "yellow"}}> <label>{this.props.label}</label> <input type={this.props.type} value={this.state.val} onChange={(evt)=> { this.setState({ val: evt.target.value }) }}></input> </div> ) } clear() { this.setState({ val: "" }) } setValue(value) { this.setState({ val: value }) } } export default class App extends Component { userName = React.createRef(); password = React.createRef() render() { return ( <div> <h1>登录页面</h1> <Filed ref={this.userName} label="用户名" type="text" ></Filed> <Filed ref={this.password} label="密码" type="password"></Filed> <button onClick={()=> { console.log(this.userName.current); console.log(this.password.current); console.log(`账号:${this.userName.current.state.val}-密码:${this.password.current.state.val}`); }}>登录</button> <button onClick={()=> { this.userName.current.clear() this.password.current.clear() }}>取消</button> <div style={{background: "#ff2121"}}> <svg style={{width: "20px"}} t="1669106904741" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="3653" width="200" height="200"><path d="M513.506307 974.330764c-62.755276 0-123.643018-12.295024-180.971701-36.543288-55.363935-23.416316-105.081267-56.935734-147.772578-99.626022-42.690288-42.690288-76.209706-92.408643-99.626022-147.771555-24.248264-57.328683-36.542264-118.216425-36.542264-180.971701s12.295024-123.643018 36.542264-180.972724c23.416316-55.364959 56.935734-105.08229 99.626022-147.773601s92.408643-76.210729 147.772578-99.628068c57.328683-24.248264 118.216425-36.543288 180.971701-36.543288 62.755276 0 123.643018 12.295024 180.972724 36.543288 55.364959 23.417339 105.08229 56.936757 147.773601 99.628068s76.211752 92.409666 99.628068 147.773601c24.248264 57.329706 36.543288 118.217449 36.543288 180.972724s-12.295024 123.643018-36.543288 180.971701c-23.417339 55.363935-56.93778 105.081267-99.628068 147.771555-42.691311 42.691311-92.409666 76.210729-147.773601 99.627045C637.150348 962.03574 576.262606 974.330764 513.506307 974.330764zM513.506307 82.074274c-57.69912 0-113.661689 11.296277-166.334329 33.5757-50.884924 21.522176-96.587825 52.338019-135.840828 91.591021-39.251979 39.251979-70.066799 84.955904-91.588975 135.841851-22.278399 52.67264-33.574676 108.636233-33.574676 166.335353s11.296277 113.662713 33.574676 166.334329c21.522176 50.885947 52.338019 96.588849 91.588975 135.839805 39.251979 39.251979 84.955904 70.067822 135.840828 91.589998 52.67264 22.278399 108.635209 33.574676 166.334329 33.574676s113.662713-11.295254 166.335353-33.574676c50.885947-21.522176 96.589872-52.338019 135.841851-91.589998 39.253002-39.250956 70.068845-84.955904 91.591021-135.839805 22.278399-52.67264 33.5757-108.635209 33.5757-166.334329 0-57.69912-11.296277-113.662713-33.5757-166.335353-21.522176-50.885947-52.338019-96.589872-91.591021-135.841851s-84.955904-70.068845-135.841851-91.591021C627.170043 93.370551 571.205427 82.074274 513.506307 82.074274z" p-id="3654"></path><path d="M507.742023 722.763215c-10.376325 0-18.786878-8.411577-18.786878-18.786878L488.955144 590.364789c0-73.891917 51.429323-99.112322 96.804766-121.363092 52.704362-25.845645 98.219999-48.165999 88.23867-139.822512-3.546779-32.550347-19.739577-57.901735-48.130184-75.352175-28.942169-17.788132-69.626777-26.617218-117.695562-25.511024-34.110889 0.781806-66.710354 10.963703-94.273107 29.447682-27.16264 18.215874-48.102554 43.559075-60.554144 73.290213-4.009314 9.56996-15.017018 14.07967-24.585955 10.07138-9.570983-4.00829-14.07967-15.015995-10.07138-24.585955 15.304568-36.540218 40.990576-67.654866 74.283844-89.981361 33.519418-22.478967 73.057923-34.859949 114.341165-35.806507 55.296397-1.2689 103.106286 9.476839 138.229225 31.064506 38.252209 23.51046 61.008492 59.228963 65.808822 103.294574 12.836353 117.857245-54.744835 150.998039-109.046578 177.627537-21.070898 10.332323-40.972157 20.091594-54.872748 33.641191-14.455223 14.089903-20.901029 30.739095-20.901029 53.986565L526.530948 703.976336C526.528901 714.351638 518.117324 722.763215 507.742023 722.763215z" p-id="3655"></path><path d="M531.058055 810.18631c0 10.721179-8.691963 19.413142-19.417235 19.413142-10.721179 0-19.413142-8.691963-19.413142-19.413142 0-10.725272 8.691963-19.417235 19.413142-19.417235C522.366092 790.768051 531.058055 799.461037 531.058055 810.18631z" p-id="3656"></path></svg> </div> </div> ) } }
非父子组件通信
-
状态提升(中间人模式)
- React中的状态提升概括来说,就是将多个组件需要共享的状态提升到它们最近的父组件上,在父组件上改变这个状态然后通过props分发给子组件
/* * @Author: HuangBingQuan [email protected] * @Date: 2022-11-23 15:08:14 * @LastEditors: HuangBingQuan [email protected] * @LastEditTime: 2022-11-23 16:34:32 * @FilePath: /react_test/src/02-advanced/06-中间人模式.js * @Description: 这是默认设置,请设置`customMade`, 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE */ import React, { Component } from 'react' import axios from 'axios'; import './css/communinaion.scss' class FilmItem extends Component { render() { // console.log(this.props); let { name, poster, grade, synopsis, callback } = this.props; return ( <div className='filmitem' onClick={(e)=> { callback(synopsis) }}> <img src={poster} alt={name}></img> <h4>{name}</h4> <div>观众评分:{grade}</div> </div> ) } } class FilmDetail extends Component { render() { return ( <div className='filmdetail'>{this.props.con}</div> ) } } export default class App extends Component { constructor() { super(); this.state = { filmList: [], con: "" } this.getData()(); } getData() { return async()=> { let { data: { data: { films } } } = await axios({ url: "/test.json", method: "get" }); console.log( films ); this.setState({ filmList: films }) } } render() { return ( <div> { this.state.filmList.map(item => <FilmItem key={item.filmId} {...item} callback={(value)=> { this.setState({ con: value }) }}></FilmItem> ) } <FilmDetail con={this.state.con}></FilmDetail> </div> ) } }
-
发布订阅模式实现
/* * @Author: HuangBingQuan [email protected] * @Date: 2022-11-23 15:08:14 * @LastEditors: HuangBingQuan [email protected] * @LastEditTime: 2022-11-23 18:54:31 * @FilePath: /react_test/src/02-advanced/06-中间人模式.js * @Description: 这是默认设置,请设置`customMade`, 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE */ import React, { Component } from 'react' import axios from 'axios'; import './css/communinaion.scss' // 调度中心 var bus = { list: [], // 订阅 subscribe(callback) { // console.log(callback); this.list.push(callback) }, // 发布 publish(text) { // 遍历注册集合,执行回调函数 this.list.forEach(callback => { callback && callback(text) }) } } class FilmItem extends Component { render() { // console.log(this.props); let { name, poster, grade, synopsis } = this.props; return ( <div className='filmitem' onClick={(e)=> { bus.publish(synopsis) }}> <img src={poster} alt={name}></img> <h4>{name}</h4> <div>观众评分:{grade}</div> </div> ) } } class FilmDetail extends Component { constructor() { super(); this.state = { con: "" } bus.subscribe((con)=> { this.setState({ con, }) }) } render() { return ( <div className='filmdetail'>{this.state.con}</div> ) } } export default class App extends Component { constructor() { super(); this.state = { filmList: [], } this.getData()(); } getData() { return async()=> { let { data: { data: { films } } } = await axios({ url: "/test.json", method: "get" }); console.log( films ); this.setState({ filmList: films }) } } render() { return ( <div> { this.state.filmList.map(item => <FilmItem key={item.filmId} {...item} callback={(value)=> { this.setState({ con: value }) }}></FilmItem> ) } <FilmDetail></FilmDetail> </div> ) } }
-
context状态数传参
import React, { Component } from 'react' const GlobalContext = React.createContext() class App extends Component { constructor() { super(); this.state = { info: "" } } render() { return ( // 供应数据 <GlobalContext.Provider value={{ info: this.state.info, changeInfo: (val)=> { this.setState({ info: val }) } }}> <Test></Test> </GlobalContext.Provider> ) } } class Test extends Component { render() { return ( // 消费数据 <GlobalContext.Consumer> { (value)=> { return ( <div>{value.info}</div> ) } } </GlobalContext.Consumer> ) } }