后端程序员入门react笔记(四)-综合运用,写一个小demo

样式模块化

有时候我们会遇到这样的问题,有两个css对一个class声明了样式,这样的话后引入的css会覆盖前面的css样式,导致样式冲突,那么我们怎么解决这种问题呢,我们可以使用样式的模块化,我们起名一个index.module.css和一个content.module.css
在这里插入图片描述

  • 我们在代码中这样使用
import React from "react";
import index from "./css/index.module.css";
import content from "./css/content.module.css";

class Hello extends React.Component {
    render() {
        console.log("i am render")
        return (
            <ul>
                <h1 className={index.title}>i am index.css</h1>
                <h1 className={content.title}>i am content.css</h1>
            </ul>
        )
    }
}
//导出组件
export default Hello;

Webstorm中的快捷键

  • rcc+tab键:用ES6模块系统创建一个React组件类
import React, {Component} from 'react';

class Hello extends Component {
    render() {
        return (
            <div>
                
            </div>
        );
    }
}

export default Hello;
  • rccp+tab键:创建一个带有PropTypes和ES6模块系统的React组件类
import React, {Component} from 'react';
import PropTypes from 'prop-types';

class Hello extends Component {
    render() {
        return (
            <div>
                
            </div>
        );
    }
}

Hello.propTypes = {};

export default Hello;
  • rcfc+tab键:创建一个带有PropTypes和所有生命周期方法以及ES6模块系统的React组件类
  • rcjc+tab键:用ES6模块系统创建一个React组件类(无导出)
  • rdp+tab键:快速生成defaultProps
  • rpc+tab键:用PropTypes和ES6 moudle系统创建一个React纯组件类
  • rrc+tab键:创建一个连接到redux的React组件类
  • rrdc+tab键:创建一个通过dispatch连接到redux的React组件类
  • rsc+tab键:创建没有PropTypes和ES6模块系统的无状态React组件
  • rscp+tab键:创建有PropTypes和ES6模块系统的无状态React组件
  • rsf+tab键:以命名函数的形式创建无状态的React组件,不使用PropTypes
  • rsfp+tab键:使用PropTypes将无状态的React组件作为命名函数创建
  • rsi+tab键:创建无状态的React组件,不使用PropTypes和ES6模块系统,但使用隐式返回和道具
  • rwwd+tab键:在没有导入的情况下,在ES6模块系统中创建一个有构造函数、空状态、proptypes和导出的React组件类。(主要用于React时,proptype由webpack提供插件提供)

组件化编码

我们通过前面应该也能认识到,我们写react,包括npm运行react,其实都是从index.js入口文件开始,那么index.js的格式至关重要

//引入核心库
import React from 'react';
//引入dom库
import ReactDOM from 'react-dom';
//引入组件
import Hello from './components/Hello';
ReactDOM.render(<Hello />,document.getElementById('root'))

拆分组件的原则

  • 单一职责原则:每个组件只负责一项功能,这样可以使组件的代码更加简洁易读,并且方便维护和重用。

  • 可复用性:每个组件都应该尽量独立,以便在其他地方重复使用。

  • 组件之间的耦合度:组件之间应该尽量避免耦合,这样可以使得组件的代码更加灵活,便于维护和修改。

  • 让组件尽可能小:尽可能使组件的代码行数少,这样可以使代码更易读,并且方便维护。

  • 可读性:组件的代码应该有良好的结构,并且有适当的注释,便于阅读和理解。

案列 TodoList

页面渲染

我先把一个没有任何功能的页面渲染出来,给一些初始数据

  • 我们在入口文件中,分别声明 引入的核心文件,dom库,和组件
//引入核心库
import React from 'react';
//引入dom库
import ReactDOM from 'react-dom';
//引入组件
import App from "./App";
ReactDOM.render(<App />,document.getElementById('root'))
  • 在App组件初始化一些数据并返回页面结构,并将初始化数据通过props传给list
import React, {Component} from 'react';
import "./App.css"
import Header from "./components/Header/Header"
import Footer from "./components/Footer/Footer"
import List from "./components/List/List"
class App extends Component {
    //初始状态
    state={
        todos:[
            {id:1,text:"吃饭",done:false}
            ,{id:2,text:"睡觉",done:false}
            ,{id:3,text:"打豆豆",done:false}
            ,{id:4,text:"看动画",done:false}
        ]
    }
    render() {
        return (
            <div className="todo-container">
                <div className="todo-wrap">
                    {/*引入header组件*/}
                    <Header />
                    {/*引入list组件*/}
                    <List data={this.state.todos} />
                    {/*引入Footer组件*/}
                    <Footer />
                </div>
                
            </div>
        );
    }
}

export default App;
  • List.jsx
import React, {Component} from 'react';
import Item from "../Item/Item";
import "./List.css"
class List extends Component {
    //限制属性类型
    render() {
        const todos = this.props.data;
        return (
            <ul className="todo-main">
                {todos.map((todo, index) => {
                    // 将todo对象作为props传给Item组件  ...默认和对象同名
                    return <Item key={todo.id} {...todo}></Item>;
                })}
            </ul>
        );
    }
}

export default List;
  • Item.jsx
import React, {Component} from 'react';
import "./Item.css"

class Item extends Component {
    render() {
        const {id,text,done}=this.props
        return (
            <li style={{backgroundColor: 'white'}}>
                <label >
                    <input type="checkbox"/>
                    <span>{text}</span>
                </label>
                <button className="btn btn-danger" style={{display:'none'}}>删除</button>
            </li>
        );
    }
}
export default Item;
  • Header.jsx
import React, {Component} from 'react';

class Header extends Component {
    render() {
        return (
            <div className="todo-header">
                <input type="text" placeholder="请输入你的任务名称,按回车键确认"/>
            </div>
        );
    }
}
export default Header;
  • Footer.jsx
import React, {Component} from 'react';

class Footer extends Component {
    render() {
        return (
            <div className="todo-footer">
                <label>
                    <input type="checkbox"/>
                    <span>
                        <span>已经完成2/全部5</span>
                    </span>
                </label>
                <button className="btn btn-danger">清除已完成任务</button>
            </div>
        );
    }
}

export default Footer;
  • 最终样式如下
    在这里插入图片描述

功能实现

鼠标悬浮

  • 首先我们来实现第一个功能,从简单功能入手,鼠标悬浮,列表背景色变色,并展示删除按钮,触发事件是onMouseEnter,鼠标离开恢复原状,触发事件是onMouseLeave,展示是否完成的状态,我们开始编写
class Item extends Component {

    //定义状态
    state={mouse:false}
               //接收参数
    handleMouse=(flag)=>{
       return ()=>{
           this.setState({
               mouse:flag
           })
       }
    }
    render() {
        const {id,text,done}=this.props
        const flag=this.state.mouse
        return (                                                                  //传入参数
            <li style={{backgroundColor: flag?'#ddd':'white'}} onMouseEnter={this.handleMouse(true)}
            onMouseLeave={this.handleMouse(false)}>
                <label >
                    <input type="checkbox" checked={done}/>
                    <span>{text}</span>
                </label>
                <button className="btn btn-danger" style={{display:flag?'block':'none'}}>删除</button>
            </li>
        );
    }
}

勾选和删除

  • 实现勾选和删除功能,当点击选中按钮的时候,触发的操作是onChange,删除按钮的触发事件是onClick,我们来实现一下,因为我们操作的数据来源于App.jsx的state,为了方便操作数据,我们将方法写在App.jsx里面,然后通过props传递给组件
    updateTodo=(id,done)=>{
        const todos=this.state.todos
        //遍历找到对应的todo,创建一个新的数组对象
        const newTodos=todos.map((todo)=>{
            if (todo.id===id){//改变状态
                return {...todo,done:done}
            }else{
                return todo
            }
        })
        this.setState({todos:newTodos})
    }

    deleteTodo=(id)=>{
        const todos=this.state.todos
        const newTodos=todos.filter((todo)=>{
           return todo.id !==id
        })
        this.setState({todos:newTodos})
    }
  • Item.jsx
    handelChange=(id)=>{
        return (e)=>{
            //根据id和checked状态更新数据
            this.props.updateTodo(id,e.target.checked)
        }
    }
    del=(id)=>{
        return ()=>{
            this.props.deleteTodo(id)
        }
    }
    render() {
        const {id,text,done}=this.props
        const flag=this.state.mouse
        return (                                                                  //传入参数
            <li style={{backgroundColor: flag?'#ddd':'white'}} onMouseEnter={this.handelMouse(true)}
            onMouseLeave={this.handelMouse(false)}>
                <label >
                    <input type="checkbox" checked={done}  onChange={this.handelChange(id)}/>
                    <span>{text}</span>
                </label>
                <button className="btn btn-danger" onClick={this.del(id)} style={{display:flag?'block':'none'}}>删除</button>
            </li>
        );
    }

添加

  • 接下来我们再实现一个添加todo的功能,触发事件就是Onkeyup
    App.js
    addTodo=(todo)=>{
        const todos=this.state.todos
        const newTodos=[...todos,todo]
        console.log(newTodos);
        this.setState({todos:newTodos})
    }

header.jsx

    addTodo = (e) => {
        // console.log(e);
        const {keyCode, target} = e
        if (keyCode === 13) {
            const todo = {
                id: nanoid(),
                text: target.value,
                done: false
            }
            // console.log(todo);
            this.props.addTodo(todo);
            target.value = '';
        }
    }

全选和一键清除

  • app.js
    checkAll=(bool)=>{//全选或者取消全选
        const todos=this.state.todos
        const newTodos=todos.map((todo)=>{
            return {...todo,done:bool}
        })
        this.setState({todos:newTodos})
    }

    delAll=()=>{
        const todos=this.state.todos
        const newTodos=todos.filter((todo)=>{
            return !todo.done
        })
        this.setState({todos:newTodos})
    }
  • footer.jsx
class Footer extends Component {
    state = {
        checked: false
    };

    //如果是状态false 点击后全选中
    checkAll = () => {
        const  checked=this.state.checked;
        this.props.checkAll(!checked);
        this.setState({
            checked: !this.state.checked
        });
    };
    delAll = () => {
        this.props.delAll();
    };

    render() {
        const {todos} = this.props;
        const total=todos.length

        const doneCount=todos.reduce((prev,cur)=>{
            return prev+(cur.done?1:0);
        },0)

        return (
            <div className="todo-footer">
                <label>
                    <input onChange={this.checkAll} checked={this.state.checked} type="checkbox"/>
                    <span>
                        <span>已经完成{doneCount}/全部{total}</span>
                    </span>
                </label>
                <button className="btn btn-danger" onClick={this.delAll}>清除已完成任务</button>
            </div>
        );
    }
}

react的事件监听大全

react所有事件监听

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/404931.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Shell好用的工具: cut

目标 使用cut可以切割提取指定列\字符\字节的数据 介绍 cut 译为“剪切, 切割” , 是一个强大文本处理工具&#xff0c;它可以将文本按列进行划分的文本处理。cut命令逐行读入文本&#xff0c;然后按列划分字段并进行提取、输出等操作。 语法 cut [options] filename opti…

Vue(学习笔记)

什么是Vue Vue是一套构建用户界面的渐进式框架 构建用户界面&#xff1a; 基于数据渲染出用户可以看到的界面 渐进式&#xff1a; 所谓渐进式就是循序渐进&#xff0c;不一定非得把Vue中的所有API都学完才能开发Vue&#xff0c;可以学一点开发一点 创建Vue实例 比如就上面…

java面向对象上:类的结构之一

目录 1.相同点 2.不同点 2.1 在类中声明的位置的不同 2.2 关于权限修饰符的不同 2.3 默认初始化值的情况&#xff1a; 2.4 在内存中加载的位置 补充&#xff1a;回顾变量的分类&#xff1a; 方式一&#xff1a;按照数据类型&#xff1a; 方式二&#xff1a;按照在类中…

01_02_mysql06_(视图-存储过程-函数(变量、流程控制与游标)-触发器)

视图 使用 视图一方面可以帮我们使用表的一部分而不是所有的表&#xff0c;另一方面也可以针对不同的用户制定不同的查询视图。比如&#xff0c;针对一个公司的销售人员&#xff0c;我们只想给他看部分数据&#xff0c;而某些特殊的数据&#xff0c;比如采购的价格&#xff0…

第九节HarmonyOS 常用基础组件24-Navigation

1、描述 Navigation组件一般作为Page页面的根容器&#xff0c;通过属性设置来展示的标题栏、工具栏、导航栏等。 2、子组件 可以包含子组件&#xff0c;推荐与NavRouter组件搭配使用。 3、接口 Navigation() 4、属性 名称 参数类型 描述 title string|NavigationComm…

alibabacloud学习笔记06(小滴课堂)

讲Sentinel流量控制详细操作 基于并发线程进行限流配置实操 在浏览器打开快速刷新会报错 基于并发线程进行限流配置实操 讲解 微服务高可用利器Sentinel熔断降级规则 讲解服务调用常见的熔断状态和恢复 讲解服务调用熔断例子 我们写一个带异常的接口&#xff1a;

Win32 获取EXE/DLL文件版本信息

CFileVersion.h #pragma once#include <windows.h> #include <string> #include <tchar.h>#ifdef _UNICODE using _tstring std::wstring; #else using _tstring std::string; #endif// 版本号辅助类 class CVersionNumber { public:// 无参构造CVersionN…

【Pytorch深度学习开发实践学习】B站刘二大人课程笔记整理lecture06 Logistic回归

【Pytorch深度学习开发实践学习】B站刘二大人课程笔记整理lecture06 Logistic回归 课程网址 Pytorch深度学习实践 部分课件内容&#xff1a; import torchx_data torch.tensor([[1.0],[2.0],[3.0]]) y_data torch.tensor([[0.0],[0.0],[1.0]])class LogisticRegressionModel(…

PYTHON-使用正则表达式进行模式匹配

目录 Python 正则表达式Finding Patterns of Text Without Regular ExpressionsFinding Patterns of Text with Regular ExpressionsCreating Regex ObjectsMatching Regex ObjectsReview of Regular Expression MatchingMore Pattern Matching with Regular ExpressionsGroupi…

【数据结构】排序(2)

目录 一、快速排序&#xff1a; 1、hoare(霍尔)版本&#xff1a; 2、挖坑法&#xff1a; 3、前后指针法&#xff1a; 4、非递归实现快速排序&#xff1a; 二、归并排序&#xff1a; 1、递归实现归并排序&#xff1a; 2、非递归实现归并排序&#xff1a; 三、排序算法…

白酒:陈酿过程中的氧化还原反应与酒体老化

在云仓酒庄豪迈白酒的陈酿过程中&#xff0c;氧化还原反应与酒体老化是影响酒品质的重要因素。陈酿是白酒生产中不可或缺的一环&#xff0c;通过陈酿可以使酒体更加协调、口感更加醇厚。而氧化还原反应作为陈酿过程中的重要化学反应&#xff0c;对酒体的老化起着关键作用。 首先…

Python列表:灵活多变的数据结构

文章目录 一、列表1.创建列表2.访问列表元素3.修改列表元素4.添加元素5.删除元素 二、列表脚本操作符1.连接运算符 2.重复运算符 * 三、列表函数&方法1.函数1.1 len() 函数1.2 max() 函数1.3 min() 函数1.4 sum() 函数1.5 list() 函数 2.方法2.1 append() 方法2.2 extend()…

nginx 具体介绍

一&#xff0c;nginx 介绍 &#xff08;一&#xff09;nginx 与apache 1&#xff0c; Apache event 模型 相对于 prefork 模式 可以同时处理更多的请求 相对于 worker 模式 解决了keepalive场景下&#xff0c;长期被占用的线程的资源浪费问题 因为有监听线程&#…

江科大STM32学习笔记(上)

STM32F103xx 前言外设篇GPIO输出GPIO位结构GPIO模式外设的GPIO配置查看实战1&#xff1a; 如何进行基本的GPIO输入输出 OLED显示屏及调试Keil的调试模式演示 EXTI外部中断NVIC基本结构EXTI结构代码实战2&#xff1a;如何使用中断和对射式红外传感器&#xff06;旋转编码器 TIM&…

嵌入式基础准备 | 初识嵌入式AI

1、嵌入式设备发展 1、第一代&#xff1a;2000年开始 单片机 最简单的电子产品 遥控器&#xff0c;烟雾报警器 裸机编程 RTOS 智能音箱&#xff0c;路由器&#xff0c;摄像头 实时性要求高的操作系统&#xff08;马上请求&#xff0c;马上响应&#xff09; 2、第二代&#xf…

程序媛的mac修炼手册-- 小白入门Java篇

最近因为要用CiteSpace做文献综述&#xff0c;间接接触Java了。所以&#xff0c;继Python、C之后&#xff0c;又要涉猎Java了。刺激&#xff01;&#xff01; 由于CiteSpace与Java要求版本高度匹配&#xff0c;有个匹配详情明天为大家讲解。总之&#xff0c;我的Java之旅开始于…

华清远见作业第四十一天——Qt(第三天)

思维导图&#xff1a; 编程 完善对话框&#xff0c;点击登录对话框&#xff0c;如果账号和密码匹配&#xff0c;则弹出信息对话框&#xff0c;给出提示”登录成功“&#xff0c;提供一个Ok按钮&#xff0c;用户点击Ok后&#xff0c;关闭登录界面&#xff0c;跳转到其他界面 如…

喜报 | 通付盾再次入选“苏州市网络和数据安全技术支撑单位”

近日&#xff0c;为加强苏州市网络和数据安全技术服务体系建设&#xff0c;提升网络和数据安全保障水平&#xff0c;苏州市互联网信息办公室、苏州市互联网协会发布了2024-2025年度苏州市网络和数据安全技术支撑单位名单。经过自主申报、资料审核、专家评审等环节&#xff0c;江…

「C语言进阶1」动态内存分配

目录 一、动态内存分配是什么&#xff1f; 二、为什么需要动态内存分配&#xff1f; 三、怎么进行动态内存分配&#xff1f; 1. malloc 2. calloc 3. realloc a. realloc功能解析 b. 内存泄漏和内存块被截断问题 c. 总结 4. free 四、使用动态内存分配常见的问题 【面试题】 一…

线代:认识行列式、矩阵和向量

本文主要参考的视频教程如下&#xff1a; 8小时学完线代【中国大学MOOC*小元老师】线性代数速学_哔哩哔哩_bilibili 另外这个视频可以作为补充&#xff1a; 【考研数学 线性代数 基础课】—全集_哔哩哔哩_bilibili 行列式的概念和定义 一般会由方程组来引出行列式 比如一个二阶…