React的组件通信与状态管理

目录

1. 组件通讯-概念

1.组件的特点

2.知道组件通讯意义

总结:

2. 组件通讯-props 基本使用

1.传递数据和接收数据的过程

2.函数组件使用 props 

3.类组件使用 props

总结:

3. 组件通讯-props 注意事项 

1.知道什么是单向数据流?

2.props 可以传递什么数据?任意 

总结:

4. 组件通讯-父传子方式 

1.父组件提供要传递的 state 数据

 2.给子组件标签添加属性,值为 state 中的数据

 3.子组件中通过 props 接收父组件中传递的数据

总结:

5. 组件通讯-子传父方式

1.父组件

 2.子组件

总结:

6.组件通讯-兄弟组件通讯

1.状态提升思想是什么?

2.参考代码

7. 组件通讯-context 跨级组件通讯

 1.什么是跨级组件通讯?

 2.context 怎么去理解?

3.演示使用 context 完成跨级组件通讯

总结:

1. 组件通讯-概念

了解组件通讯的意义 

大致步骤:

  • 知道组件的特点
  • 知道组件通讯意义

具体内容:

1.组件的特点

  • 组件是独立且封闭的单元,默认情况下,只能使用组件自己的数据
  • 在组件化过程中,通常会将一个完整的功能拆分成多个组件,以更好的完成整个应用的功能

2.知道组件通讯意义

  • 而在这个过程中,多个组件之间不可避免的要共享某些数据
  • 为了实现这些功能,就需要打破组件的独立封闭性,让其与外界沟通
  • 这个过程就是组件通讯

总结:

  • 组件状态是独立的,组件化之后涉及状态同步,需要进行组件通讯

2. 组件通讯-props 基本使用

能够通过 props 传递数据和接收数据 

大致步骤:

  • 传递数据和接收数据的过程
  • 函数组件使用 props
  • 类组件使用 props

具体内容:

1.传递数据和接收数据的过程

  • 使用组件的时候通过属性绑定数据,在组件内部通过 props 获取即可。

2.函数组件使用 props 

  1. // 使用组件
  2. <Hello name="jack" age="20" />
  1. // 定义组件 props包含{name:'jack',age:'20'}
  2. function Hello(props) {
  3. return <div>接收到数据:{props.name}</div>;
  4. }

3.类组件使用 props

  1. // 使用组件
  2. <Hello name="jack" age="20" />
  1. // 定义组件 props包含{name:'jack',age:'20'}
  2. class Hello extends Component {
  3. render() {
  4. return <div>接收到的数据:{this.props.age}</div>;
  5. }
  6. }

总结:

  • props 是实现组件通讯的关键,它通过使用组件绑定属性,组件内部使用 props 来传值。

3. 组件通讯-props 注意事项 

知道 props 是单项数据流只读,但是可以传递任意数据。 

大致步骤:

  • 知道什么是单向数据流
  • 知道 props 可以传递什么数据

具体内容:

1.知道什么是单向数据流

  • 单向数据流,是从上到下的,自顶而下的,数据流。
  • 好比:河流,瀑布,只能从上往下流动,上游污染下游受影响,但是下游不能影响上游。
  • 父组件传递数据给子组件,父组件更新数据子组件自动接收更新后数据,当是子组件是不能修改数据的。

2.props 可以传递什么数据?任意 

  • 字符串
  • 数字
  • 布尔
  • 数组
  • 对象
  • 函数
  • JSX (插槽)

总结:

  • props 传递数据是单向的,可以传递任意格式的数据。

4. 组件通讯-父传子方式 

通过 props 将父组件的数据传递给子组件 

大致步骤:

  • 父组件提供要传递的 state 数据
  • 给子组件标签添加属性,值为 state 中的数据
  • 子组件中通过 props 接收父组件中传递的数据

具体代码:

1.父组件提供要传递的 state 数据

  1. class Parent extends React.Component {
  2. state = {
  3. money: 10000,
  4. };
  5. render() {
  6. return (
  7. <div>
  8. <h1>父组件:{this.state.money}</h1>
  9. </div>
  10. );
  11. }
  12. }

 2.给子组件标签添加属性,值为 state 中的数据

  1. class Parent extends React.Component {
  2. state = {
  3. money: 10000
  4. }
  5. render() {
  6. return (
  7. <div>
  8. <h1>父组件:{this.state.money}</h1>
  9. + <Child money={this.state.money} />
  10. </div>
  11. )
  12. }
  13. }

 3.子组件中通过 props 接收父组件中传递的数据

  1. function Child(props) {
  2. return (
  3. <div>
  4. <h3>子组件:{props.money}</h3>
  5. </div>
  6. );
  7. }

总结:

  • 父组件声明state,在子组件标签通过属性绑定,在子组件中通过props使用。

5. 组件通讯-子传父方式

通过 props 将子组件的数据传递给父组件

大致步骤:

  • 父组件提供回调函数,通过 props 传递给子组件
  • 子组件调用 props 中的回调函数,函数可传参
  • 父组件函数的参数就是子组件传递的数据

具体代码:

1.父组件

  1. class Parent extends React.Component {
  2. state = {
  3. money: 10000,
  4. };
  5. // 回调函数
  6. buyPhone = (price) => {
  7. this.setState({
  8. money: this.state.money - price,
  9. });
  10. };
  11. render() {
  12. const { money } = this.state;
  13. return (
  14. <div>
  15. <h1>父组件:{money}</h1>
  16. <Child money={money} buyPhone={this.buyPhone} />
  17. </div>
  18. );
  19. }
  20. }

 2.子组件

  1. const Child = (props) => {
  2. const handleClick = () => {
  3. // 子组件调用父组件传递过来的回调函数
  4. props.buyPhone(5000);
  5. };
  6. return (
  7. <div>
  8. <h3>子组件:{props.money}</h3>
  9. <button onClick={handleClick}>买手机</button>
  10. </div>
  11. );
  12. };

总结:

  • 子组件如何传递数据给父组件?触发父组件传递的回调函数传入数据
  • 父组件如何接收子组件的数据?回调函数的参数是子组件传递的数据
  • 父组件数据更新后,传递给子组件的数据是否更新?自动更新

6.组件通讯-兄弟组件通讯

 通过状态提升思想完成兄弟组件数据通讯

大致步骤:

  • 状态提升思想是什么?
  • 演示通过状态提升完成兄弟组件通讯。

具体内容:

1.状态提升思想是什么?

  • 将共享状态提升到最近的公共父组件中,由公共父组件管理这个状态和修改状态的方法

 

  • 需要通讯的组件通过 props 接收状态和函数即可

2.参考代码

index.js

  1. import React, { Component } from 'react';
  2. import ReactDOM from 'react-dom';
  3. // 导入两个子组件
  4. import Jack from './Jack';
  5. import Rose from './Rose';
  6. // App 是父组件
  7. class App extends Component {
  8. // 1. 状态提升到父组件
  9. state = {
  10. msg: '',
  11. };
  12. changeMsg = (msg) => {
  13. this.setState({ msg });
  14. };
  15. render() {
  16. return (
  17. <div>
  18. <h1>我是App组件</h1>
  19. {/* 兄弟组件 1 */}
  20. <Jack changeMsg={this.changeMsg}></Jack>
  21. {/* 兄弟组件 2 */}
  22. <Rose msg={this.state.msg}></Rose>
  23. </div>
  24. );
  25. }
  26. }
  27. // 渲染组件
  28. ReactDOM.render(<App />, document.getElementById('root'));

 Jack.js

  1. import React, { Component } from 'react';
  2. export default class Jack extends Component {
  3. say = () => {
  4. // 修改数据
  5. this.props.changeMsg('you jump i look');
  6. };
  7. render() {
  8. return (
  9. <div>
  10. <h3>我是Jack组件</h3>
  11. <button onClick={this.say}></button>
  12. </div>
  13. );
  14. }
  15. }

 Rose.jsx

  1. import React, { Component } from 'react';
  2. export default class Rose extends Component {
  3. render() {
  4. return (
  5. <div>
  6. <h3>我是Rose组件-{this.props.msg}</h3>
  7. </div>
  8. );
  9. }
  10. }

7. 组件通讯-context 跨级组件通讯

掌握使用 context 实现跨级组件通讯 

大致步骤:

  • 什么是跨级组件通讯?
  • context 怎么去理解?
  • 演示使用 context 完成跨级组件通讯。

具体内容:

 1.什么是跨级组件通讯?

  • 组件间相隔多层,理解成叔侄,甚至更远的亲戚。

 2.context 怎么去理解?

  • 术语:上下文
  • 理解:一个范围,只要在这个范围内,就可以跨级组件通讯。(不需要 props 层层传递)

3.演示使用 context 完成跨级组件通讯

 index.jsx

  1. import React, { Component, createContext } from 'react'
  2. import Parent from './Parent'
  3. // 1. 创建上下文对象
  4. // @ts-ignore
  5. export const MyContext = createContext()
  6. export default class App extends Component {
  7. state = {
  8. money: 10000
  9. }
  10. updateMoney = newMoney => {
  11. this.setState({
  12. money: newMoney
  13. })
  14. }
  15. render() {
  16. return (
  17. // 2. Provider包裹确定上下文生效范围,value注入范围内可用的数据
  18. <MyContext.Provider value={{
  19. money: this.state.money,
  20. updateMoney: this.updateMoney
  21. }}>
  22. <div className="app">
  23. <h1>根组件:{this.state.money}</h1>
  24. <hr />
  25. <Parent />
  26. </div>
  27. </MyContext.Provider>
  28. )
  29. }
  30. }

 Parent.jsx

  1. import Child from './Child';
  2. const Parent = () => {
  3. return (
  4. <div className="parent">
  5. <h3>父组件:</h3>
  6. <hr />
  7. <Child />
  8. </div>
  9. );
  10. };
  11. export default Parent;

 Child.jsx

  1. import { MyContext } from './App'
  2. const Child = () => {
  3. return (
  4. // 3. 通过Consumer来消费数据,value=>{ 这里使用数据 }
  5. <MyContext.Consumer>
  6. {(value) => (
  7. <div className="child">
  8. <h5>子组件:{value.money} <button onClick={()=>value.updateMoney(5000)}>修改money</button></h5>
  9. </div>
  10. )}
  11. </MyContext.Consumer>
  12. );
  13. };
  14. export default Child;

总结:

  • 使用creatContext()创建一个上下文对象,包含:Provider Consumer 组件。
  • 使用 Provider 包裹组件,value 属性注入状态,函数,被包裹组件下的任何组件可以使用。
  • 使用 Consumer 消费 Provider 提供的数据和函数,语法{value=>使用数据和函数}

原文链接:点这里进入哦

posted @ 2023-03-23 15:39  __fairy  阅读(58)  评论(0编辑  收藏  举报