后端程序员入门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所有事件监听

相关推荐

最近更新

  1. docker php8.1+nginx base 镜像 dockerfile 配置

    2024-02-23 09:50:04       94 阅读
  2. Could not load dynamic library ‘cudart64_100.dll‘

    2024-02-23 09:50:04       101 阅读
  3. 在Django里面运行非项目文件

    2024-02-23 09:50:04       82 阅读
  4. Python语言-面向对象

    2024-02-23 09:50:04       91 阅读

热门阅读

  1. 共享之力:分布式计算的奇迹

    2024-02-23 09:50:04       57 阅读
  2. 拉伸图片覆盖整个页面的css写法

    2024-02-23 09:50:04       58 阅读
  3. Ubuntu 22.04上编译Android 13 AOSP系统并刷入Pixel 6

    2024-02-23 09:50:04       57 阅读
  4. VUE API 接口

    2024-02-23 09:50:04       55 阅读
  5. 第四章、单例模式

    2024-02-23 09:50:04       60 阅读
  6. Kotlin 中注解 @JvmOverloads 的作用

    2024-02-23 09:50:04       53 阅读
  7. Spring Boot 常用注解大全

    2024-02-23 09:50:04       48 阅读
  8. ECMAScript modules规范示例详解

    2024-02-23 09:50:04       51 阅读
  9. Selenium基础:自动化你的网页交互

    2024-02-23 09:50:04       55 阅读