【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、<Fragment></Fragment>等价于<></>

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

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;

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;

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

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

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

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

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

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

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;

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
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值