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

2021年09月15日 阅读数:1
这篇文章主要向大家介绍React---使用react脚手架搭建项目,主要内容包括基础应用、实用技巧、原理机制等方面,希望对大家有所帮助。

1、 使用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-appcss

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

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

  第四步,启动项目:npm startwebpack

1.3. react脚手架项目结构

public ---- 静态资源文件夹程序员

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

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

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

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

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 交互(从绑定事件监听开始)

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. 效果

 

本文同步分享在 博客“半指温柔乐”(CNBlog)。
若有侵权,请联系 support@oschina.cn 删除。
本文参与“OSC源创计划”,欢迎正在阅读的你也加入,一块儿分享。