• React---使用react脚手架搭建项目


    一、 使用create-react-app创建react应用

    1.1. react脚手架

    1. xxx脚手架: 用来帮助程序员快速创建一个基于xxx库的模板项目
      1. 包含了所有需要的配置(语法检查、jsx编译、devServer…)
      2. 下载好了所有相关的依赖
      3. 可以直接运行一个简单效果
    2. react提供了一个用于创建react项目的脚手架库: create-react-app
    3. 项目的整体技术架构为:  react + webpack + es6 + eslint
    4. 使用脚手架开发的项目的特点: 模块化, 组件化, 工程化

    1.2. 创建项目并启动

      第一步,全局安装:npm i -g create-react-app

      第二步,切换到想创项目的目录,使用命令:create-react-app hello-react

      第三步,进入项目文件夹:cd hello-react

      第四步,启动项目:npm start

    1.3. react脚手架项目结构

    public ---- 静态资源文件夹

    favicon.icon ------ 网站页签图标

    index.html -------- 主页面

    logo192.png ------- logo图

    logo512.png ------- logo图

    manifest.json ----- 应用加壳的配置文件

    robots.txt -------- 爬虫协议文件

    src ---- 源码文件夹

    App.css -------- App组件的样式

    App.js --------- App组件

    App.test.js ---- 用于给App做测试

    index.css ------ 样式

    index.js ------- 入口文件

    logo.svg ------- logo图

    reportWebVitals.js  --- 页面性能分析文件(需要web-vitals库的支持)

    setupTests.js  ---- 组件单元测试的文件(需要jest-dom库的支持)

    1.4. 功能界面的组件化编码流程(通用)

    1. 拆分组件: 拆分界面,抽取组件

    2. 实现静态组件: 使用组件实现静态页面效果

    3. 实现动态组件

    3.1 动态显示初始化数据

    3.1.1 数据类型

    3.1.2 数据名称

    3.1.2 保存在哪个组件

    3.2 交互(从绑定事件监听开始)

    二、案例

    1. TodoList分析

      1.拆分组件、实现静态组件,注意:className、style的写法
            2.动态初始化列表,如何确定将数据放在哪个组件的state中?
                        ——某个组件使用:放在其自身的state
                        ——某些组件使用:放在他们共同的父组件state中(官方称此操作为:状态提升)
            3.关于父子之间通信:
                    1.【父组件】给【子组件】传递数据:通过props传递
                    2.【子组件】给【父组件】传递数据:通过props传递,要求父提前给子传递一个函数
            4.注意defaultChecked 和 checked的区别,类似的还有:defaultValue 和 value, checked必须要写onChange方法配合使用
            5.状态在哪里,操作状态的方法就在哪里
     
     

    2. 代码

    (1)App.jsx

     1 import React, { Component } from 'react'
     2 import Header from './components/Header'
     3 import List from './components/List'
     4 import Footer from './components/Footer'
     5 import './App.css'
     6 
     7 export default class App extends Component {
     8     //状态在哪里,操作状态的方法就在哪里
     9 
    10     //初始化状态
    11     state = {todos:[
    12         {id:'001',name:'吃饭',done:true},
    13         {id:'002',name:'睡觉',done:true},
    14         {id:'003',name:'打代码',done:false},
    15         {id:'004',name:'逛街',done:false}
    16     ]}
    17 
    18     //addTodo用于添加一个todo,接收的参数是todo对象
    19     addTodo = (todoObj)=>{
    20         //获取原todos
    21         const {todos} = this.state
    22         //追加一个todo
    23         const newTodos = [todoObj,...todos]
    24         //更新状态
    25         this.setState({todos:newTodos})
    26     }
    27 
    28     //updateTodo用于更新一个todo对象
    29     updateTodo = (id,done)=>{
    30         //获取状态中的todos
    31         const {todos} = this.state
    32         //匹配处理数据
    33         const newTodos = todos.map((todoObj)=>{
    34             if(todoObj.id === id) return {...todoObj,done}
    35             else return todoObj
    36         })
    37         this.setState({todos:newTodos})
    38     }
    39 
    40     //deleteTodo用于删除一个todo对象
    41     deleteTodo = (id)=>{
    42         //获取原来的todos
    43         const {todos} = this.state
    44         //删除指定id的todo对象
    45         const newTodos = todos.filter((todoObj)=>{
    46             return todoObj.id !== id
    47         })
    48         //更新状态
    49         this.setState({todos:newTodos})
    50     }
    51 
    52     //checkAllTodo用于全选
    53     checkAllTodo = (done)=>{
    54         //获取原来的todos
    55         const {todos} = this.state
    56         //加工数据
    57         const newTodos = todos.map((todoObj)=>{
    58             return {...todoObj,done}
    59         })
    60         //更新状态
    61         this.setState({todos:newTodos})
    62     }
    63 
    64     //clearAllDone用于清除所有已完成的
    65     clearAllDone = ()=>{
    66         //获取原来的todos
    67         const {todos} = this.state
    68         //过滤数据
    69         const newTodos = todos.filter((todoObj)=>{
    70             return !todoObj.done
    71         })
    72         //更新状态
    73         this.setState({todos:newTodos})
    74     }
    75 
    76     render() {
    77         const {todos} = this.state
    78         return (
    79             <div className="todo-container">
    80                 <div className="todo-wrap">
    81                     <Header addTodo={this.addTodo}/>
    82                     <List todos={todos} updateTodo={this.updateTodo} deleteTodo={this.deleteTodo}/>
    83                     <Footer todos={todos} checkAllTodo={this.checkAllTodo} clearAllDone={this.clearAllDone}/>
    84                 </div>
    85             </div>
    86         )
    87     }
    88 }

    (2) Header.jsx

     1 import React, { Component } from 'react'
     2 import PropTypes from 'prop-types'
     3 import {nanoid} from 'nanoid'
     4 import './index.css'
     5 
     6 export default class Header extends Component {
     7 
     8     //对接收的props进行:类型、必要性的限制
     9     static propTypes = {
    10         addTodo:PropTypes.func.isRequired
    11     }
    12 
    13     //键盘事件的回调
    14     handleKeyUp = (event)=>{
    15         //解构赋值获取keyCode,target
    16         const {keyCode,target} = event
    17         //判断是否是回车按键
    18         if(keyCode !== 13) return
    19         //添加的todo名字不能为空
    20         if(target.value.trim() === ''){
    21             alert('输入不能为空')
    22             return
    23         }
    24         //准备好一个todo对象
    25         const todoObj = {id:nanoid(),name:target.value,done:false}
    26         //将todoObj传递给App
    27         this.props.addTodo(todoObj)
    28         //清空输入
    29         target.value = ''
    30     }
    31 
    32     render() {
    33         return (
    34             <div className="todo-header">
    35                 <input onKeyUp={this.handleKeyUp} type="text" placeholder="请输入你的任务名称,按回车键确认"/>
    36             </div>
    37         )
    38     }
    39 }

    (3) List.jsx

     1 import React, { Component } from 'react'
     2 import PropTypes from 'prop-types'
     3 import Item from '../Item'
     4 import './index.css'
     5 
     6 export default class List extends Component {
     7 
     8     //对接收的props进行:类型、必要性的限制
     9     static propTypes = {
    10         todos:PropTypes.array.isRequired,
    11         updateTodo:PropTypes.func.isRequired,
    12         deleteTodo:PropTypes.func.isRequired,
    13     }
    14 
    15     render() {
    16         const {todos,updateTodo,deleteTodo} = this.props
    17         return (
    18             <ul className="todo-main">
    19                 {
    20                     todos.map( todo =>{
    21                         return <Item key={todo.id} {...todo} updateTodo={updateTodo} deleteTodo={deleteTodo}/>
    22                     })
    23                 }
    24             </ul>
    25         )
    26     }
    27 }

    (4) Item.jsx

     1 import React, { Component } from 'react'
     2 import './index.css'
     3 
     4 export default class Item extends Component {
     5 
     6     state = {mouse:false} //标识鼠标移入、移出
     7 
     8     //鼠标移入、移出的回调
     9     handleMouse = (flag)=>{
    10         return ()=>{
    11             this.setState({mouse:flag})
    12         }
    13     }
    14 
    15     //勾选、取消勾选某一个todo的回调
    16     handleCheck = (id)=>{
    17         return (event)=>{
    18             this.props.updateTodo(id,event.target.checked)
    19         }
    20     }
    21 
    22     //删除一个todo的回调
    23     handleDelete = (id)=>{
    24         if(window.confirm('确定删除吗?')){
    25             this.props.deleteTodo(id)
    26         }
    27     }
    28 
    29 
    30     render() {
    31         const {id,name,done} = this.props
    32         const {mouse} = this.state
    33         return (
    34             <li style={{backgroundColor:mouse ? '#ddd' : 'white'}} onMouseEnter={this.handleMouse(true)} onMouseLeave={this.handleMouse(false)}>
    35                 <label>
    36                     <input type="checkbox" checked={done} onChange={this.handleCheck(id)}/>
    37                     <span>{name}</span>
    38                 </label>
    39                 <button onClick={()=> this.handleDelete(id) } className="btn btn-danger" style={{display:mouse?'block':'none'}}>删除</button>
    40             </li>
    41         )
    42     }
    43 }

    3. 效果

  • 相关阅读:
    测试爬虫
    流式大数据处理的三种框架:Storm,Spark和Samza
    redo日志
    HTTP协议之chunk编码(分块传输编码
    QWidget 实现 打破布局 或者 当前窗体内的 弹窗 (借助伪造实现)
    How to use kingshard building a MySQL cluster
    转载: Qt 学习之路 2归档
    Python与机器人技术
    Nginx配置正向代理
    使用Chrony配置 NTP
  • 原文地址:https://www.cnblogs.com/le220/p/14686814.html
Copyright © 2020-2023  润新知