• 后端程序员入门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;
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17

    Webstorm中的快捷键

    • rcc+tab键:用ES6模块系统创建一个React组件类
    import React, {Component} from 'react';
    
    class Hello extends Component {
        render() {
            return (
                <div>
                    
                </div>
            );
        }
    }
    
    export default Hello;
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 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;
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 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'))
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    拆分组件的原则

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

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

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

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

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

    案列 TodoList

    页面渲染

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

    • 我们在入口文件中,分别声明 引入的核心文件,dom库,和组件
    //引入核心库
    import React from 'react';
    //引入dom库
    import ReactDOM from 'react-dom';
    //引入组件
    import App from "./App";
    ReactDOM.render(<App />,document.getElementById('root'))
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 在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;
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 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;
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 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;
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 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;
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 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;
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 最终样式如下
      在这里插入图片描述

    功能实现

    鼠标悬浮

    • 首先我们来实现第一个功能,从简单功能入手,鼠标悬浮,列表背景色变色,并展示删除按钮,触发事件是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>
            );
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27

    勾选和删除

    • 实现勾选和删除功能,当点击选中按钮的时候,触发的操作是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})
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 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>
            );
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25

    添加

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

    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 = '';
            }
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14

    全选和一键清除

    • 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})
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 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>
            );
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38

    react的事件监听大全

    react所有事件监听

  • 相关阅读:
    RSA算法中,为什么需要的是两个素数?
    PVC 塑料片BS 476-6 火焰传播性能测定
    leetcode 139. 单词拆分
    【信号去噪】基于麻雀搜索算法优化VM实现信号去噪附matlab代码
    STM32之蜂鸣器实验
    GPT-4 Alpha:OpenAI的革命性升级
    encodeURI与encodeURIComponent的使用
    算法----BF算法&KMP算法
    如何让ChatGPT生成图片?
    Pyside6 Qlabel显示图片、文本
  • 原文地址:https://blog.csdn.net/qq_39962403/article/details/136216783