• 【React的组件&组件间的通信(父向子,子向父,同级组件通信)】


    一、React项目的入口文件(create-react-app)

    React项目的入口文件(create-react-app):index.js

    在这里插入图片描述

    1、React.StrictMode:检测工具,检查React项目是否存在潜在风险。不会渲染任何真是的DOM。可以用在任何地方:

    (1)识别不具备生命周期的组件

    (2)检查旧式字符串的用法

    (3)检查弃用的方法

    在这里插入图片描述

    二、React的组件

    1、什么是组件?

    什么是组件:是视图的抽象

    2、组件的分类:

    (1)函数组件:推荐使用

    (2)类组件:必须继承自React.Component类,并且必须有render方法,在render方法中用return语句来定义要渲染的视图。

    a、组件文件的扩展名可以是.js,也可以是.jsx

    b、等价于<>

    c、在return中必须要有一个根标签

    3、组件间的通信

    组件间的通信:是单向数据流设计,即数据只能从父级向子级一层一层向下传递

    (1)父级向子级通信:在父组件中调用子组件时,只需要将想要传递的数据加在子组件的属性上,然后子组件内部通过props属性来接收。

    ☀️举个例子:

    创建data目录,再创建一个子文件index.js文件

    let data = {
        famliy:{
            title:'家人',
            list:[
                {name:'爸爸'},
                {name:'妈妈'}
            ]
        },
        friend:{
            title:'朋友',
            list:[
                {name:'郭靖'},
                {name:'黄蓉'},
                {name:'老顽童'}
            ]
        },
        customer:{
            title:'客户',
            list:[
                {name:'阿里'},
                {name:'腾讯'},
                {name:'小米'}
    ]
        }
    }
    export default data
    
    • 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

    App.js父组件:

    import logo from './logo.svg';
    import './App.css';
    import First from "./components/First"
    import data from './data/index'
    
    function App() {
      return (
         <div className="App">
          <header className="App-header">
            <img src={logo} className="App-logo" alt="logo" />
          </header>
            {
                Object.keys(data).map((itemName)=>{
                    return <First key ={itemName} dlData={ data[itemName] } />
                })
            }
        </div>
      );
    
    }
    
    export default App;
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22

    First.jsx子组件:

    import React,{ Component } from "react";
    class First extends Component {
        render() {
            let {dlData} = this.props
            return (
                <>
                    <dl className="first-group">
                        <dt>{dlData.title}</dt>
                        {
                            dlData.list.map((item, index) => {
                                return <dd key={index}> {item.name} </dd>
                            })
                        }
                    </dl>
                </>
            )
        }
    }
    export default First;
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19

    效果展示:
    在这里插入图片描述

    (2)子组件向父组件传递数据:React是单向数据流,无法从子组件直接将数据传递给父组件。可以在父组件中定义好回调函数,把回调函数传递给子组件,利用回调函数向父组件传递数据。

    ☀️举个例子:

    Father.jsx父组件:

    import React,{Component} from "react";
    import Son from "./Son"
    class Father extends Component{
        constructor(props) {
            super(props);
    
        }
        showInfo(name){//回调函数
            console.log('子组件的Name:'+name)
        }
        render(){
            return(
                <Son openShow = {this.showInfo}/>//将回调函数传递给子组件
            )
        }
    }
    export  default  Father
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17

    Son.jsx子组件:

    import React,{Component } from "react";
    class Son extends Component{
        constructor(props) {
            super(props);
        }
        render(){
            let { openShow } = this.props
            return (
                <button onClick={()=>{
                    openShow('刘备')
                }}>我是子组件</button>
            )
        }
    }
    export default  Son;
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15

    效果显示:
    点击按钮:
    在这里插入图片描述在这里插入图片描述

    (3)同级组件之间的传递:React是单向数据流,同级组件之间无法直接传递数据。可以通过父组件来完成同级组件之间的数据传递。

    注意:组件的状态state的使用

    a、在React中,组件就是一种状态机,组件会根据状态的不同输出不同的UI。需要交互时,只需要把交互和状态关联起来。

    b、定义state:state是组件实例的一个属性,它的值是一个对象在类组件的构造方法中定义
    this.state = {}
    c、更新state:调用setState方法。因为视图和state是绑定的,所以当state更新后,视图也会重新渲染。

    过程:调用setState方法后,会根据setState传入的值,对state进行修改,根据修改后的state生成新的虚拟的DOM,将新的虚拟DOM和老的虚拟的DOM进行对比,找到修改点对象视图进行更新

    注意组件的函数绑定this的方法:组件中的普通函数是没有绑定this的(如下例子中的changeName函数要用箭头函数)

    a、使用bind()函数绑定this:在构造函数中定义以下语句

    this.函数名 = this.函数名.bind(this)

    b、使用箭头函数

    ☀️举个例子:

    Counter.jsx代码段:

    import React,{ Component } from "react";
    import Counter1 from "./Counter1";
    import Counter2 from "./Counter2";
    class Counter extends Component{
        constructor(props) {
            super(props);
            this.state = { //组件的状态属性
                name: '西游',
                age : 50,
                counter1Name:''
            }
            this.changeName = this.changeName.bind(this);//绑定this
        }
        changeName(sonName){ //没有使用箭头函数:找到this
    
            this.setState({
                counter1Name: sonName
            })
        }
        render() {
            let { name,age } = this.state
            return (
                <>
                    <p>姓名:{ name }</p>
                    <p>年龄:{ age }</p>
    
                    <button onClick={()=>{
                        this.setState({
                            age: ++age
                        })
                    }}>过了一年</button>
                    <br/><br/>
                    <Counter1  modifyName={ this.changeName }/>
                    <Counter2  counter1Name={this.state.counter1Name }/>
                </>
            )
        }
    }
    export default Counter;
    
    • 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

    Counter1.jsx代码段:

    import React,{Component} from "react";
    
    export default  class Counter1 extends Component{
        constructor(props) {
            super(props);
            this.state = {
                name: '张良'
            }
        }
        render() {
            let { modifyName } = this.props
            return (
                <div className="div1">
                    <button onClick={()=>{
                          modifyName(this.state.name)
                       }
                    }>我是Counter1</button>
                    <br/><br/>
                    <p>姓名:{ this.state.name }</p>
                </div>
            )
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23

    Counter2.jsx代码段:

    import React,{ Component } from "react";
    
    export default  class Counter2 extends Component{
        render() {
            let { counter1Name } = this.props
            return (
                <div className="div2">
                    <button>我是Counter2</button>
                    <br/><br/>
                    <p>
                        来自Counter1的Name: { counter1Name }
                    </p>
                </div>
            )
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16

    App.js代码段:

    import './App.css';
     import  Counter from './components/Counter'
    import CounterTwo from "./components/CounterTwo";
     import CounterOne from "./components/CounterOne";
    function App() {
        return (
              <div className="App">
                  <Counter/>
                  <CounterOne/>
                  <CounterTwo/>
              </div>
        )
    }
    
    export default App;
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16

    index.css代码段:

    .div1{
      width:100px;
      height:100px;
      background-color: red;
      margin-left: 100px;
    }
    .div2{
      width:300px;
      height:100px;
      background-color: blue;
      margin-left: 200px;
      color:white;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13

    在这里插入图片描述

  • 相关阅读:
    【算法 | 概述初识】时间复杂度和空间复杂度(我不信看完这篇文章你还不懂)
    初识自动驾驶技术之旅 第一课 学习笔记
    计算机毕业设计之java+javaweb的影院管理系统-电影院管理系统
    Qt 工程添加windows库文件
    面试宝典-Mysql篇
    怎么理解Fiber,Fiber解决了什么问题
    vue父子组件实现表单双向绑定
    CSS3动画animation
    Python基本数据类型转换Type_conversion
    <Python>PyQt5自己编写一个音乐播放器(优化版)
  • 原文地址:https://blog.csdn.net/m0_46839072/article/details/126441559