React工程化——webpack构建react工程化——react脚手架解析——函数组件间的通信父—子——函数组件事件绑定——todolist案例

本文介绍React的基础概念,包括函数组件与类组件的创建及使用,探讨组件间的数据传递方式,如父传子通信,以及如何利用Context实现跨组件通信。同时讲解事件处理机制和TODOLIST案例实现。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

类组件,函数组件
标签绑定事件,事件的绑定的this指向问题。
父子组件通信

webpack

引入核心库,babel
在这里插入图片描述


react脚手架

React团队维护开发的create-react-app来创建React新的单页应用项目的最佳方式。
React脚手架(create-react-app)意义
💘 脚手架是官方推荐,零配置,无需手动配置繁琐的工具即可使用
💘 充分利用 Webpack,Babel,ESLint等工具辅助项目开发
💘 关注业务,而不是工具配置,提升创建项目时间,把更多的时间用到开发中

create-react-app会配置你的开发环境,以便使你能够使用最新的
JavaScript特性,提供良好的开发体验,并为生产环境优化你的应用程序。你需要在你的机器上安装 Node >= 16

项目名称全小写,不能用空格大写字母 现在使用脚手架创建的react版本为最新版本18.x

npx create-react-app myapp     // 创建项目,时间会有点的久
cd myapp   // 进入到安装项目中
npm start   // 启动项目

现在我的项目启动是:

yarn start
yarn build

在这里插入图片描述
在这里插入图片描述
💘建议在工作中,不要创建 npx create-react-app 工具来创建项目,而是使用原项目进行,create-react-app工具,它只能创建最新版本的react项目

yarn包管理工具
## 安装一下 yarn工具,它不是自带的,需要安装
npm i -g yarn

组件。

组件允许你将 UI 拆分为独立可复用的代码片段,并对每个片段进行独立构思。从概念上类似于 JavaScript 类或函数。它接受任意的入参(props),并返回用于描述页面展示内容的 React元素(jsx)。 定义好的组件一定要有返回值

  • react中定义组件的方式2种
    • 💘函数组件(无状态组件/UI组件)
    • 💘类组件(状态组件/容器组件)

函数创建组件

如果你在vscode中安装了jsx插件,则可以用 rfc创建函数组件
快捷键:rcf
✅函数组件(无状态组件):使用JS的函数创建组件
✅函数名称必须以大写字母开头,
✅函数组件必须有返回值(jsx)/null,表示该组件的结构,且内容必须有顶级元素

import React from 'react';

const App = () => {
    return (
        <div>
            <h1>我爱你</h1>
        </div>
    );
}

export default App;

类创建组件

✅使用ES6语法的class创建的组件(状态组件)
✅类名称必须要大写字母开头
✅类组件要继承React.Component父类,从而可以使用父类中提供的方法或者属性
✅类组件必须提供 render 方法,用于页面结构渲染,结构必须要有顶级元素,且必须return去返回

import React, { Component } from 'react';

class App extends Component {
    render() {
        return (
            <div>
                <h1>我爱你</h1>
            </div>
        );
    }
}
export default App;

函数组件间的通信——父传子

父子组件传值(props[只读属性])
1️⃣组件间传值,在React中是通过只读属性 props 来完成数据传递的。
2️⃣props:接受任意的入参,并返回用于描述页面展示内容的 React元素。
3️⃣props中的数据是不能被修改的,只能读取。
4️⃣props是一个单向数据流。 父流向子,子不能直接去修改props中的数据
通过自定义属性,可以向子组件传递数据 ,此数据它是单向数据流,子组件不能直接修改

import React from 'react';

function fn(){
    return console.log("fn");
}
const Child = (props) => {
 let {a} = props//也可以通过解构的方式将变量赋值
    return (
        <div>
            <h2>{props.a}</h2>
            <h2>{a}</h2>
        </div>
    );
}

const App = () => {
    return (
        <div>
            <Child a={"aaaa"} str={"110"} c={{key:"我爱你"}} className={"active"} fn={fn} num={120} />
        </div>
    );
}

export default App;

在这里插入图片描述

类组件间的通信——父传子

💥子组件它是通过 成员属性this.props来接受参数的
必须在render() {}里面渲染使用。

import React, { Component } from 'react';
class Child extends Component {
    render() {
        let {title,fn} = this.props;//必须解构使用,注意this指向
        console.log(fn);
        console.log(fn());
        console.log(fn()());
        return (
            <div>
                <div>
                    {title}  
                </div>
                <div>
                    {fn()()}
                </div>
            </div>
        );
    }
}
class App extends Component {
	//fn = function(params) { return params}	       
    fn = (arg)=>()=>()=>arg;//柯理化
    render() {
        return (
            <div>
                <Child title={123} fn={this.fn(100)}></Child>
            </div>
        );
    }
}
export default App;

在这里插入图片描述
在这里插入图片描述
注意:

  • 类组件的父组件成员属性值的赋值。
  • 子组件在render() {}进行解构赋值使用。
  • 函数到底是返回数值还是返回一个函数要清楚。
  • 通过给子组件添加方法属性,注意自己需不需要加()

跨组件通信

在react没有类似vue中的事件总线来解决这个问题。在实际的项目中,当需要组件间跨级访问信息时,如果还使用组件层层传递props,此时代码显得不那么优雅,甚至有些冗余。在react中,我们还可以使用context来实现跨级父子组件间的通信。
Context 提供了一个无需为每层组件手动添加 props,就能在组件树间进行数据传递的方法。Context 设计目的是为了共享那些对于一个组件树而言是“全局”的数据。
在React的Context中,数据我们可当成商品,发布数据的组件会用provider身份(卖方),接收数据的组件使用consumer身份(卖方)
在这里插入图片描述
创建Context对象
当React渲染一个订阅了这个Context对象的组件,这个组件会从组件树中离自身最近的那个匹配的Provider中读取到当前的context值。

// 定义全局context,全局数据源 
import { createContext } from "react"
export default createContext()

发布消息
在App.jsx组件中发布消息,这样所有的组件都可以消费它的消息。

在这里插入代码片

函数组件事件绑定

React 元素的事件处理和 DOM 元素的很相似,但是有一点语法上的不同:

  • React 事件的命名采用小驼峰式,而不是纯小写。
onClick  onChange
  • 使用 JSX 语法时你需要传入一个函数作为事件处理函数,而不是一个字符串。
onClick={clickHandler}// 注函数或方法不能用小括号
onClick={this.fn} // 绑定实现方法一定要用{函数或方法}   
  • 一般情况下,绑定的事件方法是不会加小括号,如果要加小括号,则定义绑定方法时,一定要返回一函数
import React from 'react';
const Child = (props) => {
    let {num} = props
    // console.log(num);
    return (
        <div>
            <h2>{num}</h2>
        </div>
    );
}
const App = () => {
    let num = 1;
    const clickHandler = ()=>{
        // console.log(++num);
        return ()=>{
            console.log(++num);
        }
    }
    return (
        <div>
            <Child num={num}></Child>
            {/* <button onClick={clickHandler}>点我+1</button> */}
            <button onClick={clickHandler()} >点我+1</button>
        </div>
    );
}

export default App;

类组件事件绑定

💖类组件与函数组件绑定事件是差不多的,只是在类组件中绑定事件函数的时候类需要用到this,代表指向当前的类的引用,在函数中不需要调用this

import React, { Component } from 'react';

class Child extends Component {
    render() {
        let {num} = this.props
        return (
            <div>
                <h1>{num}</h1>
            </div>
        );
    }
}

class App extends Component {
    num=1;
    clickHandler = ()=>{
        this.num++;
        console.log(this.num);
        console.log(this);//App
        this.forceUpdate()//通知视图更新
    }
    render() {
        return (
            <div>
                <Child num={this.num}></Child>
                <button onClick={this.clickHandler}>+1</button>
            </div>
        );
    }
}
export default App;

例如todo事件的完成:

  • 建议使用 箭头函数定义成员属性,因为传统的function找不见这个this的指向问题
clickHandler = ()=>{
	console.log(this);//App
}
clickHandler = function () {
	console.log(this);//undefined
}

值得注意的是:react事件,在没有写小括号的时候会主动的把event事件对象传给你

clickHandler = (event)=>{
    console.log(event.target);//<input type="text">
}

onKeyUp事件完成todolist功能

  • 类组件中提供一个方法,可以强制让视图更新
  • this.forceUpdate()//通知视图更新
todos = [{id:Date.now(),msg:"我爱你"}]
enterkHandler = (event)=>{
    if(event.keyCode === 13){
        this.todos.unshift({
            id:Date.now(),
            msg:event.target.value.trim()
        })
        event.target.value = ''
    }
    this.forceUpdate()//通知视图更新
   
}

给input添加键盘事件,给button添加点击事件

TODOLIST案例实现

import React, { Component } from 'react';

class App extends Component {
    todos = [{id:Date.now(),msg:"我爱你"}]
    enterkHandler = (event)=>{
        if(event.keyCode === 13){
            this.todos.unshift({
                id:Date.now(),
                msg:event.target.value.trim()
            })
            event.target.value = ''
        }
        this.forceUpdate()//通知视图更新
       
    }
    onClickHanler = (evt)=>{
        this.todos = this.todos.filter((item)=>
            item.id != evt.target.parentElement.id
        )
        console.log(this.todos);
        this.forceUpdate()//通知视图更新
    }
    render() {
        return (
            <div>
                <input type="text" onKeyUp={this.enterkHandler}/>
                <ul>{
                    this.todos.map(item=>(<li key={item.id} id={item.id}>{item.msg}<button onClick={this.onClickHanler}>x</button></li>))
                }</ul>
            </div>
        );
    }
}

export default App;

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

勇敢*牛牛

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值