【React的组件+组件间的通信(父->子、子->父、同级)】

一、React项目的入口文件

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、<Fragment></Fragment>等价于<></>
c、在return中必须要有一个根标签

3、组件间的通信

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

(1)父级向子级通信

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

💥举例:

index.js(自定义文件夹data下的子文件,并不是上文的入口文件index.js)代码段

let data = {
    family:{
        title:'家人',
        list:[
            { name:'爸爸'},
            { name:'妈妈'}
        ]
    },
    friend:{
        title: '朋友',
        list:[
            { name:'郭靖'},
            { name:'黄蓉'},
            { name:'老顽童'}
        ]
    },
    customer:{
        title:'客户',
        list:[
            { name:'阿里'},
            { name:'腾讯'},
            { name:'小米'}
        ]
    }
}
export default data;

App.js父组件代码段

import data from "./data";
function App() {
  return (
    <div className="App">
    {
        Object.keys(data).map((itemName) => {
          return <First key={itemName} dlData={data[itemName]}/>
    })
      }
    </div>
  );
}

export default App;

First.jsx(子组件)代码段:

import React,{Component} from "react";
//如果没有导入Component,则需要写成 class First extends React.Component
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;

在这里插入图片描述

(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;

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;

App.js代码段

import Father from "./components/Father";
function App() {
  return (
    <div className="App">
         <Father/>
    </div>
  );
}

export default App;

在这里插入图片描述

(3)同级组件之间的传递

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

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

  • 在React中,组件就是一种状态机,组件会根据状态的不同输出不同的UI。需要交互时,只需要把交互和状态关联起来
  • 定义state:state是组件实例的一个属性,它的值是一个对象,在类组件的构造方法中定义。this.state = {}
  • 更新state:调用setState方法。因为视图和state是绑定的,所以当state更新后,视图也会重新渲染。
    过程:调用setState方法后,会根据setState传入的值,对state进行修改,state生成新的虚拟的DOM,将新的虚拟的DOM和老的虚拟的DOM进行对比,
    找到修改点对视图进行更新。

注意:组件中的函数绑定this的方法:组件中的普通函数是没有绑定this的

  • 使用bind()函数绑定this:在构造函数中定义以下语句this.函数名 = this.函数名.bind(this)
  • 使用箭头函数

💥举例:

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:'70',
            counter1Name:''
        }
        this.changeName=this.changeName.bind(this)  //绑定this

    }
    changeName(sonName){ //没有使用箭头函数:找到this

        this.setState({
            counter1Name: sonName
        })
    }

    //普通函数没有this,改为使用箭头函数:找到this
   /* changeName=(sonName)=>{
        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;

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>
        )
    }
}

Counter2.jsx代码段:

import React,{Component} from "react";

class Counter2 extends Component{

    render() {
        let {counter1Name}=this.props
        return (
            <div className='div2'>
                <button>我是Counter2</button>
                <br/><br/>
                <p>
                    来自Counter1的Name:{ counter1Name }
                </p>
            </div>
        )

    }
}
export default Counter2;

App.js代码段:

import './App.css';
import Counter from "./components/Counter";

function App() {
  return (
    <div className="App">
        <Counter/>
    </div>
  );
}

export default App;

index.css代码段:

.div1{
  width: 100px;
  height: 100px;
  background-color: red;
  margin: 100px auto;
}

.div2{
  width: 250px;
  height: 150px;
  color: #eeeeee;
  background-color: blue;
  margin: 100px auto;
}

在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值