React的组件通信与状态管理
目录
1. 组件通讯-概念
了解组件通讯的意义
大致步骤:
- 知道组件的特点
- 知道组件通讯意义
具体内容:
1.组件的特点
- 组件是
独立且封闭
的单元,默认情况下,只能使用组件自己的数据 - 在组件化过程中,通常会将一个完整的功能拆分成多个组件,以更好的完成整个应用的功能
2.知道组件通讯意义
- 而在这个过程中,多个组件之间不可避免的要
共享
某些数据 - 为了实现这些功能,就需要打破组件的独立封闭性,让其与外界沟通
- 这个过程就是组件通讯
总结:
- 组件状态是独立的,组件化之后涉及状态同步,需要进行组件通讯
2. 组件通讯-props 基本使用
能够通过 props 传递数据和接收数据
大致步骤:
- 传递数据和接收数据的过程
- 函数组件使用 props
- 类组件使用 props
具体内容:
1.传递数据和接收数据的过程
- 使用组件的时候通过属性绑定数据,在组件内部通过 props 获取即可。
2.函数组件使用 props
- // 使用组件
- <Hello name="jack" age="20" />
- // 定义组件 props包含{name:'jack',age:'20'}
- function Hello(props) {
- return <div>接收到数据:{props.name}</div>;
- }
3.类组件使用 props
- // 使用组件
- <Hello name="jack" age="20" />
- // 定义组件 props包含{name:'jack',age:'20'}
- class Hello extends Component {
- render() {
- return <div>接收到的数据:{this.props.age}</div>;
- }
- }
总结:
- props 是实现组件通讯的关键,它通过使用组件绑定属性,组件内部使用 props 来传值。
3. 组件通讯-props 注意事项
知道 props 是单项数据流只读,但是可以传递任意数据。
大致步骤:
- 知道什么是单向数据流
- 知道 props 可以传递什么数据
具体内容:
1.知道什么是单向数据流?
- 单向数据流,是从上到下的,
自顶而下
的,数据流。 - 好比:河流,瀑布,只能从上往下流动,上游污染下游受影响,但是下游不能影响上游。
- 父组件传递数据给子组件,父组件更新数据子组件自动接收更新后数据,当是子组件是不能修改数据的。
2.props 可以传递什么数据?任意
- 字符串
- 数字
- 布尔
- 数组
- 对象
- 函数
- JSX (插槽)
总结:
- props 传递数据是单向的,可以传递任意格式的数据。
4. 组件通讯-父传子方式
通过 props 将父组件的数据传递给子组件
大致步骤:
- 父组件提供要传递的 state 数据
- 给子组件标签添加属性,值为 state 中的数据
- 子组件中通过 props 接收父组件中传递的数据
具体代码:
1.父组件提供要传递的 state 数据
- class Parent extends React.Component {
- state = {
- money: 10000,
- };
- render() {
- return (
- <div>
- <h1>父组件:{this.state.money}</h1>
- </div>
- );
- }
- }
2.给子组件标签添加属性,值为 state 中的数据
- class Parent extends React.Component {
- state = {
- money: 10000
- }
- render() {
- return (
- <div>
- <h1>父组件:{this.state.money}</h1>
- + <Child money={this.state.money} />
- </div>
- )
- }
- }
3.子组件中通过 props 接收父组件中传递的数据
- function Child(props) {
- return (
- <div>
- <h3>子组件:{props.money}</h3>
- </div>
- );
- }
总结:
- 父组件声明
state,
在子组件标签通过属性绑定
,在子组件中通过props
使用。
5. 组件通讯-子传父方式
通过 props 将子组件的数据传递给父组件
大致步骤:
- 父组件提供回调函数,通过 props 传递给子组件
- 子组件调用 props 中的回调函数,函数可传参
- 父组件函数的参数就是子组件传递的数据
具体代码:
1.父组件
- class Parent extends React.Component {
- state = {
- money: 10000,
- };
- // 回调函数
- buyPhone = (price) => {
- this.setState({
- money: this.state.money - price,
- });
- };
- render() {
- const { money } = this.state;
- return (
- <div>
- <h1>父组件:{money}</h1>
- <Child money={money} buyPhone={this.buyPhone} />
- </div>
- );
- }
- }
2.子组件
- const Child = (props) => {
- const handleClick = () => {
- // 子组件调用父组件传递过来的回调函数
- props.buyPhone(5000);
- };
- return (
- <div>
- <h3>子组件:{props.money}</h3>
- <button onClick={handleClick}>买手机</button>
- </div>
- );
- };
总结:
- 子组件如何传递数据给父组件?触发父组件传递的回调函数传入数据
- 父组件如何接收子组件的数据?回调函数的参数是子组件传递的数据
- 父组件数据更新后,传递给子组件的数据是否更新?自动更新
6.组件通讯-兄弟组件通讯
通过状态提升思想完成兄弟组件数据通讯
大致步骤:
- 状态提升思想是什么?
- 演示通过状态提升完成兄弟组件通讯。
具体内容:
1.状态提升思想是什么?
- 将共享状态提升到最近的公共父组件中,由公共父组件管理这个状态和修改状态的方法
- 需要通讯的组件通过 props 接收状态和函数即可
2.参考代码
index.js
- import React, { Component } from 'react';
- import ReactDOM from 'react-dom';
-
- // 导入两个子组件
- import Jack from './Jack';
- import Rose from './Rose';
-
- // App 是父组件
- class App extends Component {
- // 1. 状态提升到父组件
- state = {
- msg: '',
- };
-
- changeMsg = (msg) => {
- this.setState({ msg });
- };
-
- render() {
- return (
- <div>
- <h1>我是App组件</h1>
- {/* 兄弟组件 1 */}
- <Jack changeMsg={this.changeMsg}></Jack>
- {/* 兄弟组件 2 */}
- <Rose msg={this.state.msg}></Rose>
- </div>
- );
- }
- }
-
- // 渲染组件
- ReactDOM.render(<App />, document.getElementById('root'));
Jack.js
- import React, { Component } from 'react';
-
- export default class Jack extends Component {
- say = () => {
- // 修改数据
- this.props.changeMsg('you jump i look');
- };
- render() {
- return (
- <div>
- <h3>我是Jack组件</h3>
- <button onClick={this.say}>说</button>
- </div>
- );
- }
- }
Rose.jsx
- import React, { Component } from 'react';
-
- export default class Rose extends Component {
- render() {
- return (
- <div>
- <h3>我是Rose组件-{this.props.msg}</h3>
- </div>
- );
- }
- }
7. 组件通讯-context 跨级组件通讯
掌握使用 context 实现跨级组件通讯
大致步骤:
- 什么是跨级组件通讯?
- context 怎么去理解?
- 演示使用 context 完成跨级组件通讯。
具体内容:
1.什么是跨级组件通讯?
- 组件间相隔多层,理解成叔侄,甚至更远的亲戚。
2.context 怎么去理解?
- 术语:上下文
- 理解:一个范围,只要在这个范围内,就可以跨级组件通讯。(不需要 props 层层传递)
3.演示使用 context 完成跨级组件通讯
index.jsx
- import React, { Component, createContext } from 'react'
- import Parent from './Parent'
-
- // 1. 创建上下文对象
- // @ts-ignore
- export const MyContext = createContext()
-
- export default class App extends Component {
- state = {
- money: 10000
- }
- updateMoney = newMoney => {
- this.setState({
- money: newMoney
- })
- }
- render() {
- return (
- // 2. Provider包裹确定上下文生效范围,value注入范围内可用的数据
- <MyContext.Provider value={{
- money: this.state.money,
- updateMoney: this.updateMoney
- }}>
- <div className="app">
- <h1>根组件:{this.state.money}</h1>
- <hr />
- <Parent />
- </div>
- </MyContext.Provider>
- )
- }
- }
Parent.jsx
- import Child from './Child';
- const Parent = () => {
- return (
- <div className="parent">
- <h3>父组件:</h3>
- <hr />
- <Child />
- </div>
- );
- };
-
- export default Parent;
Child.jsx
- import { MyContext } from './App'
-
- const Child = () => {
- return (
- // 3. 通过Consumer来消费数据,value=>{ 这里使用数据 }
- <MyContext.Consumer>
- {(value) => (
- <div className="child">
- <h5>子组件:{value.money} <button onClick={()=>value.updateMoney(5000)}>修改money</button></h5>
- </div>
- )}
- </MyContext.Consumer>
- );
- };
-
- export default Child;
总结:
- 使用
creatContext()
创建一个上下文对象,包含:Provider
Consumer
组件。 - 使用
Provider
包裹组件,value
属性注入状态,函数
,被包裹组件下的任何组件可以使用。 - 使用
Consumer
消费Provider
提供的数据和函数,语法{value=>使用数据和函数}
原文链接:点这里进入哦