React---使用react脚手架搭建项目
<h2><strong>一、 </strong><strong>使用</strong><strong>create-react-app</strong><strong>创建</strong><strong>react</strong><strong>应用</strong></h2><h3><strong>1.1. react</strong><strong>脚手架</strong></h3>
<ol>
<li>xxx脚手架: 用来帮助程序员快速创建一个基于xxx库的模板项目<ol>
<li><span style="font-family: 微软雅黑">包含了所有需要的配置(语法检查、</span>jsx编译、devServer…)</li>
<li>下载好了所有相关的依赖</li>
<li>可以直接运行一个简单效果</li>
</ol></li>
<li>react提供了一个用于创建react项目的脚手架库: <strong>create-react-app</strong></li>
<li>项目的整体技术架构为: <strong>react + webpack + es6 + eslint</strong></li>
<li>使用脚手架开发的项目的特点: <strong>模块化, 组件化, 工程化</strong></li>
</ol>
<h3><strong>1.2. </strong><strong>创建项目并启动</strong></h3>
<p><strong> 第一步</strong>,全局安装:<strong>npm i -g create-react-app</strong></p>
<p><strong> 第二步</strong>,切换到想创项目的目录,使用命令:<strong>create-react-app hello-react</strong></p>
<p><strong> 第三步</strong>,进入项目文件夹:<strong>cd hello-react</strong></p>
<p><strong> 第四步</strong>,启动项目:<strong>npm start</strong></p>
<h3><strong>1.3. react</strong><strong>脚手架项目结构</strong></h3>
<p style="margin-left: 30px"><strong>public </strong>---- <strong>静态资源文件夹</strong></p>
<p style="margin-left: 60px">favicon.icon ------ 网站页签图标</p>
<p style="margin-left: 60px"><strong>index.html</strong><strong> -------- </strong><strong>主页面</strong></p>
<p style="margin-left: 60px">logo192.png ------- logo图</p>
<p style="margin-left: 60px">logo512.png ------- logo图</p>
<p style="margin-left: 60px">manifest.json ----- 应用加壳的配置文件</p>
<p style="margin-left: 60px">robots.txt -------- 爬虫协议文件</p>
<p style="margin-left: 30px"><strong>src ---- 源码文件夹</strong></p>
<p style="margin-left: 60px">App.css -------- App组件的样式</p>
<p style="margin-left: 60px"><strong>App.js </strong><strong>--------- </strong><strong>App组件</strong></p>
<p style="margin-left: 60px">App.test.js ---- <span style="font-family: 微软雅黑">用于给</span>App做测试</p>
<p style="margin-left: 60px">index.css ------ 样式</p>
<p style="margin-left: 60px"><strong>index.js</strong><strong> </strong><strong>-</strong><strong>------ </strong><strong>入口文件</strong></p>
<p style="margin-left: 60px">logo.svg ------- logo图</p>
<p style="margin-left: 60px">reportWebVitals.js --- <span style="font-family: 微软雅黑">页面性能分析文件</span>(需要web-vitals库的支持)</p>
<p style="margin-left: 60px">setupTests.js ---- <span style="font-family: 微软雅黑">组件单元测试的文件</span>(需要jest-dom库的支持)</p>
<h3><strong>1.4. </strong><strong>功能界面的组件化编码流程(通用)</strong></h3>
<p style="margin-left: 30px">1. 拆分组件: 拆分界面,抽取组件</p>
<p style="margin-left: 30px">2. 实现静态组件: 使用组件实现静态页面效果</p>
<p style="margin-left: 30px">3. 实现动态组件</p>
<p style="margin-left: 60px">3.1 动态显示初始化数据</p>
<p style="margin-left: 90px">3.1.1 数据类型</p>
<p style="margin-left: 90px">3.1.2 数据名称</p>
<p style="margin-left: 90px">3.1.2 保存在哪个组件</p>
<p style="margin-left: 60px">3.2 交互(从绑定事件监听开始)</p>
<h2>二、案例</h2>
<p><strong>1. TodoList<strong>分析</strong></strong></p>
<div>
<div> 1.拆分组件、实现静态组件,注意:className、style的写法</div>
<div> 2.动态初始化列表,如何确定将数据放在哪个组件的<strong>state</strong>中?</div>
<div> ——某个组件使用:放在其自身的<strong>state</strong>中</div>
<div> ——某些组件使用:放在他们共同的父组件<strong>state</strong>中(官方称此操作为:状态提升)</div>
<div> 3.关于父子之间通信:</div>
<div> 1.【父组件】给【子组件】传递数据:通过<strong>props</strong>传递</div>
<div> 2.【子组件】给【父组件】传递数据:通过<strong>props</strong>传递,要求父提前给子传递一个函数</div>
<div> 4.注意<strong>defaultChecked </strong>和 <strong>checked</strong>的区别,类似的还有:<strong>defaultValue </strong>和 <strong>value, <strong>checked必须要写onChange方法配合使用</strong></strong></div>
<div> 5.状态在哪里,操作状态的方法就在哪里</div>
<div> </div>
<div> </div>
<div><strong><img src="https://img2020.cnblogs.com/blog/1217233/202104/1217233-20210421202110564-1180896923.png"></strong></div>
</div>
<p><strong>2. 代码</strong></p>
<p><strong>(1)App.jsx</strong></p>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 128, 128, 1)"> 1</span> import React, { Component } from 'react'
<span style="color: rgba(0, 128, 128, 1)"> 2</span> import Header from './components/Header'
<span style="color: rgba(0, 128, 128, 1)"> 3</span> import List from './components/List'
<span style="color: rgba(0, 128, 128, 1)"> 4</span> import Footer from './components/Footer'
<span style="color: rgba(0, 128, 128, 1)"> 5</span> import './App.css'
<span style="color: rgba(0, 128, 128, 1)"> 6</span>
<span style="color: rgba(0, 128, 128, 1)"> 7</span> export <span style="color: rgba(0, 0, 255, 1)">default</span><span style="color: rgba(0, 0, 0, 1)"> class <strong>App</strong> extends Component {
</span><span style="color: rgba(0, 128, 128, 1)"> 8</span> <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">状态在哪里,操作状态的方法就在哪里</span>
<span style="color: rgba(0, 128, 128, 1)"> 9</span>
<span style="color: rgba(0, 128, 128, 1)">10</span> <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">初始化状态</span>
<span style="color: rgba(0, 128, 128, 1)">11</span> <strong>state</strong> =<span style="color: rgba(0, 0, 0, 1)"> {todos:[
</span><span style="color: rgba(0, 128, 128, 1)">12</span> {id:'001',name:'吃饭',done:<span style="color: rgba(0, 0, 255, 1)">true</span><span style="color: rgba(0, 0, 0, 1)">},
</span><span style="color: rgba(0, 128, 128, 1)">13</span> {id:'002',name:'睡觉',done:<span style="color: rgba(0, 0, 255, 1)">true</span><span style="color: rgba(0, 0, 0, 1)">},
</span><span style="color: rgba(0, 128, 128, 1)">14</span> {id:'003',name:'打代码',done:<span style="color: rgba(0, 0, 255, 1)">false</span><span style="color: rgba(0, 0, 0, 1)">},
</span><span style="color: rgba(0, 128, 128, 1)">15</span> {id:'004',name:'逛街',done:<span style="color: rgba(0, 0, 255, 1)">false</span><span style="color: rgba(0, 0, 0, 1)">}
</span><span style="color: rgba(0, 128, 128, 1)">16</span> <span style="color: rgba(0, 0, 0, 1)"> ]}
</span><span style="color: rgba(0, 128, 128, 1)">17</span>
<span style="color: rgba(0, 128, 128, 1)">18</span> <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">addTodo用于添加一个todo,接收的参数是todo对象</span>
<span style="color: rgba(0, 128, 128, 1)">19</span> <strong>addTodo</strong> = (todoObj)=><span style="color: rgba(0, 0, 0, 1)">{
</span><span style="color: rgba(0, 128, 128, 1)">20</span> <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">获取原todos</span>
<span style="color: rgba(0, 128, 128, 1)">21</span> const {todos} = <span style="color: rgba(0, 0, 255, 1)">this</span><span style="color: rgba(0, 0, 0, 1)">.state
</span><span style="color: rgba(0, 128, 128, 1)">22</span> <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">追加一个todo</span>
<span style="color: rgba(0, 128, 128, 1)">23</span> const newTodos =<span style="color: rgba(0, 0, 0, 1)">
</span><span style="color: rgba(0, 128, 128, 1)">24</span> <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">更新状态</span>
<span style="color: rgba(0, 128, 128, 1)">25</span> <span style="color: rgba(0, 0, 255, 1)">this</span><span style="color: rgba(0, 0, 0, 1)">.setState({todos:newTodos})
</span><span style="color: rgba(0, 128, 128, 1)">26</span> <span style="color: rgba(0, 0, 0, 1)"> }
</span><span style="color: rgba(0, 128, 128, 1)">27</span>
<span style="color: rgba(0, 128, 128, 1)">28</span> <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">updateTodo用于更新一个todo对象</span>
<span style="color: rgba(0, 128, 128, 1)">29</span> <strong>updateTodo</strong> = (id,done)=><span style="color: rgba(0, 0, 0, 1)">{
</span><span style="color: rgba(0, 128, 128, 1)">30</span> <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">获取状态中的todos</span>
<span style="color: rgba(0, 128, 128, 1)">31</span> const {todos} = <span style="color: rgba(0, 0, 255, 1)">this</span><span style="color: rgba(0, 0, 0, 1)">.state
</span><span style="color: rgba(0, 128, 128, 1)">32</span> <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">匹配处理数据</span>
<span style="color: rgba(0, 128, 128, 1)">33</span> const newTodos = todos.map((todoObj)=><span style="color: rgba(0, 0, 0, 1)">{
</span><span style="color: rgba(0, 128, 128, 1)">34</span> <span style="color: rgba(0, 0, 255, 1)">if</span>(todoObj.id === id) <span style="color: rgba(0, 0, 255, 1)">return</span><span style="color: rgba(0, 0, 0, 1)"> {...todoObj,done}
</span><span style="color: rgba(0, 128, 128, 1)">35</span> <span style="color: rgba(0, 0, 255, 1)">else</span> <span style="color: rgba(0, 0, 255, 1)">return</span><span style="color: rgba(0, 0, 0, 1)"> todoObj
</span><span style="color: rgba(0, 128, 128, 1)">36</span> <span style="color: rgba(0, 0, 0, 1)"> })
</span><span style="color: rgba(0, 128, 128, 1)">37</span> <span style="color: rgba(0, 0, 255, 1)">this</span><span style="color: rgba(0, 0, 0, 1)">.setState({todos:newTodos})
</span><span style="color: rgba(0, 128, 128, 1)">38</span> <span style="color: rgba(0, 0, 0, 1)"> }
</span><span style="color: rgba(0, 128, 128, 1)">39</span>
<span style="color: rgba(0, 128, 128, 1)">40</span> <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">deleteTodo用于删除一个todo对象</span>
<span style="color: rgba(0, 128, 128, 1)">41</span> <strong>deleteTodo</strong> = (id)=><span style="color: rgba(0, 0, 0, 1)">{
</span><span style="color: rgba(0, 128, 128, 1)">42</span> <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">获取原来的todos</span>
<span style="color: rgba(0, 128, 128, 1)">43</span> const {todos} = <span style="color: rgba(0, 0, 255, 1)">this</span><span style="color: rgba(0, 0, 0, 1)">.state
</span><span style="color: rgba(0, 128, 128, 1)">44</span> <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">删除指定id的todo对象</span>
<span style="color: rgba(0, 128, 128, 1)">45</span> const newTodos = todos.filter((todoObj)=><span style="color: rgba(0, 0, 0, 1)">{
</span><span style="color: rgba(0, 128, 128, 1)">46</span> <span style="color: rgba(0, 0, 255, 1)">return</span> todoObj.id !==<span style="color: rgba(0, 0, 0, 1)"> id
</span><span style="color: rgba(0, 128, 128, 1)">47</span> <span style="color: rgba(0, 0, 0, 1)"> })
</span><span style="color: rgba(0, 128, 128, 1)">48</span> <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">更新状态</span>
<span style="color: rgba(0, 128, 128, 1)">49</span> <span style="color: rgba(0, 0, 255, 1)">this</span><span style="color: rgba(0, 0, 0, 1)">.setState({todos:newTodos})
</span><span style="color: rgba(0, 128, 128, 1)">50</span> <span style="color: rgba(0, 0, 0, 1)"> }
</span><span style="color: rgba(0, 128, 128, 1)">51</span>
<span style="color: rgba(0, 128, 128, 1)">52</span> <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">checkAllTodo用于全选</span>
<span style="color: rgba(0, 128, 128, 1)">53</span> <strong>checkAllTodo</strong> = (done)=><span style="color: rgba(0, 0, 0, 1)">{
</span><span style="color: rgba(0, 128, 128, 1)">54</span> <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">获取原来的todos</span>
<span style="color: rgba(0, 128, 128, 1)">55</span> const {todos} = <span style="color: rgba(0, 0, 255, 1)">this</span><span style="color: rgba(0, 0, 0, 1)">.state
</span><span style="color: rgba(0, 128, 128, 1)">56</span> <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">加工数据</span>
<span style="color: rgba(0, 128, 128, 1)">57</span> const newTodos = todos.map((todoObj)=><span style="color: rgba(0, 0, 0, 1)">{
</span><span style="color: rgba(0, 128, 128, 1)">58</span> <span style="color: rgba(0, 0, 255, 1)">return</span><span style="color: rgba(0, 0, 0, 1)"> {...todoObj,done}
</span><span style="color: rgba(0, 128, 128, 1)">59</span> <span style="color: rgba(0, 0, 0, 1)"> })
</span><span style="color: rgba(0, 128, 128, 1)">60</span> <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">更新状态</span>
<span style="color: rgba(0, 128, 128, 1)">61</span> <span style="color: rgba(0, 0, 255, 1)">this</span><span style="color: rgba(0, 0, 0, 1)">.setState({todos:newTodos})
</span><span style="color: rgba(0, 128, 128, 1)">62</span> <span style="color: rgba(0, 0, 0, 1)"> }
</span><span style="color: rgba(0, 128, 128, 1)">63</span>
<span style="color: rgba(0, 128, 128, 1)">64</span> <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">clearAllDone用于清除所有已完成的</span>
<span style="color: rgba(0, 128, 128, 1)">65</span> <strong>clearAllDone</strong> = ()=><span style="color: rgba(0, 0, 0, 1)">{
</span><span style="color: rgba(0, 128, 128, 1)">66</span> <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">获取原来的todos</span>
<span style="color: rgba(0, 128, 128, 1)">67</span> const {todos} = <span style="color: rgba(0, 0, 255, 1)">this</span><span style="color: rgba(0, 0, 0, 1)">.state
</span><span style="color: rgba(0, 128, 128, 1)">68</span> <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">过滤数据</span>
<span style="color: rgba(0, 128, 128, 1)">69</span> const newTodos = todos.filter((todoObj)=><span style="color: rgba(0, 0, 0, 1)">{
</span><span style="color: rgba(0, 128, 128, 1)">70</span> <span style="color: rgba(0, 0, 255, 1)">return</span> !<span style="color: rgba(0, 0, 0, 1)">todoObj.done
</span><span style="color: rgba(0, 128, 128, 1)">71</span> <span style="color: rgba(0, 0, 0, 1)"> })
</span><span style="color: rgba(0, 128, 128, 1)">72</span> <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">更新状态</span>
<span style="color: rgba(0, 128, 128, 1)">73</span> <span style="color: rgba(0, 0, 255, 1)">this</span><span style="color: rgba(0, 0, 0, 1)">.setState({todos:newTodos})
</span><span style="color: rgba(0, 128, 128, 1)">74</span> <span style="color: rgba(0, 0, 0, 1)"> }
</span><span style="color: rgba(0, 128, 128, 1)">75</span>
<span style="color: rgba(0, 128, 128, 1)">76</span> <span style="color: rgba(0, 0, 0, 1)"><strong> render</strong>() {
</span><span style="color: rgba(0, 128, 128, 1)">77</span> const {todos} = <span style="color: rgba(0, 0, 255, 1)">this</span><span style="color: rgba(0, 0, 0, 1)">.state
</span><span style="color: rgba(0, 128, 128, 1)">78</span> <span style="color: rgba(0, 0, 255, 1)">return</span><span style="color: rgba(0, 0, 0, 1)"> (
</span><span style="color: rgba(0, 128, 128, 1)">79</span> <div className="todo-container">
<span style="color: rgba(0, 128, 128, 1)">80</span> <div className="todo-wrap">
<span style="color: rgba(0, 128, 128, 1)">81</span> <Header addTodo={<span style="color: rgba(0, 0, 255, 1)">this</span>.addTodo}/>
<span style="color: rgba(0, 128, 128, 1)">82</span> <List <strong>todos</strong>={todos} <strong>updateTodo</strong>={<span style="color: rgba(0, 0, 255, 1)">this</span>.updateTodo} <strong>deleteTodo</strong>={<span style="color: rgba(0, 0, 255, 1)">this</span>.deleteTodo}/>
<span style="color: rgba(0, 128, 128, 1)">83</span> <Footer <strong>todos</strong>={todos} <strong>checkAllTodo</strong>={<span style="color: rgba(0, 0, 255, 1)">this</span>.checkAllTodo} <strong>clearAllDone</strong>={<span style="color: rgba(0, 0, 255, 1)">this</span>.clearAllDone}/>
<span style="color: rgba(0, 128, 128, 1)">84</span> </div>
<span style="color: rgba(0, 128, 128, 1)">85</span> </div>
<span style="color: rgba(0, 128, 128, 1)">86</span> <span style="color: rgba(0, 0, 0, 1)"> )
</span><span style="color: rgba(0, 128, 128, 1)">87</span> <span style="color: rgba(0, 0, 0, 1)"> }
</span><span style="color: rgba(0, 128, 128, 1)">88</span> }</pre>
</div>
<p><strong>(2) Header.jsx</strong></p>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 128, 128, 1)"> 1</span> import React, { Component } from 'react'
<span style="color: rgba(0, 128, 128, 1)"> 2</span> import PropTypes from 'prop-types'
<span style="color: rgba(0, 128, 128, 1)"> 3</span> import {nanoid} from 'nanoid'
<span style="color: rgba(0, 128, 128, 1)"> 4</span> import './index.css'
<span style="color: rgba(0, 128, 128, 1)"> 5</span>
<span style="color: rgba(0, 128, 128, 1)"> 6</span> export <span style="color: rgba(0, 0, 255, 1)">default</span><span style="color: rgba(0, 0, 0, 1)"> class <strong>Header</strong> extends Component {
</span><span style="color: rgba(0, 128, 128, 1)"> 7</span>
<span style="color: rgba(0, 128, 128, 1)"> 8</span> <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">对接收的props进行:类型、必要性的限制</span>
<span style="color: rgba(0, 128, 128, 1)"> 9</span> static <strong>propTypes</strong> =<span style="color: rgba(0, 0, 0, 1)"> {
</span><span style="color: rgba(0, 128, 128, 1)">10</span> <span style="color: rgba(0, 0, 0, 1)"> addTodo:PropTypes.func.isRequired
</span><span style="color: rgba(0, 128, 128, 1)">11</span> <span style="color: rgba(0, 0, 0, 1)"> }
</span><span style="color: rgba(0, 128, 128, 1)">12</span>
<span style="color: rgba(0, 128, 128, 1)">13</span> <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">键盘事件的回调</span>
<span style="color: rgba(0, 128, 128, 1)">14</span> <strong>handleKeyUp</strong> = (event)=><span style="color: rgba(0, 0, 0, 1)">{
</span><span style="color: rgba(0, 128, 128, 1)">15</span> <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">解构赋值获取keyCode,target</span>
<span style="color: rgba(0, 128, 128, 1)">16</span> const {keyCode,target} =<span style="color: rgba(0, 0, 0, 1)"> event
</span><span style="color: rgba(0, 128, 128, 1)">17</span> <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">判断是否是回车按键</span>
<span style="color: rgba(0, 128, 128, 1)">18</span> <span style="color: rgba(0, 0, 255, 1)">if</span>(keyCode !== 13) <span style="color: rgba(0, 0, 255, 1)">return</span>
<span style="color: rgba(0, 128, 128, 1)">19</span> <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">添加的todo名字不能为空</span>
<span style="color: rgba(0, 128, 128, 1)">20</span> <span style="color: rgba(0, 0, 255, 1)">if</span>(target.value.trim() === ''<span style="color: rgba(0, 0, 0, 1)">){
</span><span style="color: rgba(0, 128, 128, 1)">21</span> alert('输入不能为空'<span style="color: rgba(0, 0, 0, 1)">)
</span><span style="color: rgba(0, 128, 128, 1)">22</span> <span style="color: rgba(0, 0, 255, 1)">return</span>
<span style="color: rgba(0, 128, 128, 1)">23</span> <span style="color: rgba(0, 0, 0, 1)"> }
</span><span style="color: rgba(0, 128, 128, 1)">24</span> <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">准备好一个todo对象</span>
<span style="color: rgba(0, 128, 128, 1)">25</span> const todoObj = {id:nanoid(),name:target.value,done:<span style="color: rgba(0, 0, 255, 1)">false</span><span style="color: rgba(0, 0, 0, 1)">}
</span><span style="color: rgba(0, 128, 128, 1)">26</span> <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">将todoObj传递给App</span>
<span style="color: rgba(0, 128, 128, 1)">27</span> <strong><span style="color: rgba(0, 0, 255, 1)">this</span><span style="color: rgba(0, 0, 0, 1)">.props.addTodo(todoObj)
</span></strong><span style="color: rgba(0, 128, 128, 1)">28</span> <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">清空输入</span>
<span style="color: rgba(0, 128, 128, 1)">29</span> target.value = ''
<span style="color: rgba(0, 128, 128, 1)">30</span> <span style="color: rgba(0, 0, 0, 1)"> }
</span><span style="color: rgba(0, 128, 128, 1)">31</span>
<span style="color: rgba(0, 128, 128, 1)">32</span> <span style="color: rgba(0, 0, 0, 1)"> render() {
</span><span style="color: rgba(0, 128, 128, 1)">33</span> <span style="color: rgba(0, 0, 255, 1)">return</span><span style="color: rgba(0, 0, 0, 1)"> (
</span><span style="color: rgba(0, 128, 128, 1)">34</span> <div className="todo-header">
<span style="color: rgba(0, 128, 128, 1)">35</span> <input <strong>onKeyUp</strong>={<span style="color: rgba(0, 0, 255, 1)">this</span>.handleKeyUp} type="text" placeholder="请输入你的任务名称,按回车键确认"/>
<span style="color: rgba(0, 128, 128, 1)">36</span> </div>
<span style="color: rgba(0, 128, 128, 1)">37</span> <span style="color: rgba(0, 0, 0, 1)"> )
</span><span style="color: rgba(0, 128, 128, 1)">38</span> <span style="color: rgba(0, 0, 0, 1)"> }
</span><span style="color: rgba(0, 128, 128, 1)">39</span> }</pre>
</div>
<p><strong>(3) List.jsx</strong></p>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 128, 128, 1)"> 1</span> import React, { Component } from 'react'
<span style="color: rgba(0, 128, 128, 1)"> 2</span> import PropTypes from 'prop-types'
<span style="color: rgba(0, 128, 128, 1)"> 3</span> import Item from '../Item'
<span style="color: rgba(0, 128, 128, 1)"> 4</span> import './index.css'
<span style="color: rgba(0, 128, 128, 1)"> 5</span>
<span style="color: rgba(0, 128, 128, 1)"> 6</span> export <span style="color: rgba(0, 0, 255, 1)">default</span><span style="color: rgba(0, 0, 0, 1)"> class <strong>List</strong> extends Component {
</span><span style="color: rgba(0, 128, 128, 1)"> 7</span>
<span style="color: rgba(0, 128, 128, 1)"> 8</span> <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">对接收的props进行:类型、必要性的限制</span>
<span style="color: rgba(0, 128, 128, 1)"> 9</span> static <strong>propTypes</strong> =<span style="color: rgba(0, 0, 0, 1)"> {
</span><span style="color: rgba(0, 128, 128, 1)">10</span> <span style="color: rgba(0, 0, 0, 1)"> todos:PropTypes.array.isRequired,
</span><span style="color: rgba(0, 128, 128, 1)">11</span> <span style="color: rgba(0, 0, 0, 1)"> updateTodo:PropTypes.func.isRequired,
</span><span style="color: rgba(0, 128, 128, 1)">12</span> <span style="color: rgba(0, 0, 0, 1)"> deleteTodo:PropTypes.func.isRequired,
</span><span style="color: rgba(0, 128, 128, 1)">13</span> <span style="color: rgba(0, 0, 0, 1)"> }
</span><span style="color: rgba(0, 128, 128, 1)">14</span>
<span style="color: rgba(0, 128, 128, 1)">15</span> <span style="color: rgba(0, 0, 0, 1)"> render() {
</span><span style="color: rgba(0, 128, 128, 1)">16</span> const {todos,updateTodo,deleteTodo} = <span style="color: rgba(0, 0, 255, 1)">this</span><span style="color: rgba(0, 0, 0, 1)">.props
</span><span style="color: rgba(0, 128, 128, 1)">17</span> <span style="color: rgba(0, 0, 255, 1)">return</span><span style="color: rgba(0, 0, 0, 1)"> (
</span><span style="color: rgba(0, 128, 128, 1)">18</span> <ul className="todo-main">
<span style="color: rgba(0, 128, 128, 1)">19</span> <span style="color: rgba(0, 0, 0, 1)"> {
</span><span style="color: rgba(0, 128, 128, 1)">20</span> <strong> todos.map</strong>( todo =><span style="color: rgba(0, 0, 0, 1)">{
</span><span style="color: rgba(0, 128, 128, 1)">21</span> <span style="color: rgba(0, 0, 255, 1)">return</span> <<strong>Item</strong> key={todo.id} <strong>{...todo}</strong> <strong>updateTodo</strong>={updateTodo} <strong>deleteTodo</strong>={deleteTodo}/>
<span style="color: rgba(0, 128, 128, 1)">22</span> <span style="color: rgba(0, 0, 0, 1)"> })
</span><span style="color: rgba(0, 128, 128, 1)">23</span> <span style="color: rgba(0, 0, 0, 1)"> }
</span><span style="color: rgba(0, 128, 128, 1)">24</span> </ul>
<span style="color: rgba(0, 128, 128, 1)">25</span> <span style="color: rgba(0, 0, 0, 1)"> )
</span><span style="color: rgba(0, 128, 128, 1)">26</span> <span style="color: rgba(0, 0, 0, 1)"> }
</span><span style="color: rgba(0, 128, 128, 1)">27</span> }</pre>
</div>
<p><strong>(4) Item.jsx</strong></p>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 128, 128, 1)"> 1</span> import React, { Component } from 'react'
<span style="color: rgba(0, 128, 128, 1)"> 2</span> import './index.css'
<span style="color: rgba(0, 128, 128, 1)"> 3</span>
<span style="color: rgba(0, 128, 128, 1)"> 4</span> export <span style="color: rgba(0, 0, 255, 1)">default</span><span style="color: rgba(0, 0, 0, 1)"> class <strong>Item</strong> extends Component {
</span><span style="color: rgba(0, 128, 128, 1)"> 5</span>
<span style="color: rgba(0, 128, 128, 1)"> 6</span> <strong>state</strong> = {mouse:<span style="color: rgba(0, 0, 255, 1)">false</span>} <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">标识鼠标移入、移出</span>
<span style="color: rgba(0, 128, 128, 1)"> 7</span>
<span style="color: rgba(0, 128, 128, 1)"> 8</span> <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">鼠标移入、移出的回调</span>
<span style="color: rgba(0, 128, 128, 1)"> 9</span> <strong>handleMouse</strong> = (flag)=><span style="color: rgba(0, 0, 0, 1)">{
</span><span style="color: rgba(0, 128, 128, 1)">10</span> <span style="color: rgba(0, 0, 255, 1)">return</span> ()=><span style="color: rgba(0, 0, 0, 1)">{
</span><span style="color: rgba(0, 128, 128, 1)">11</span> <strong><span style="color: rgba(0, 0, 255, 1)">this</span><span style="color: rgba(0, 0, 0, 1)">.setState({mouse:flag})
</span></strong><span style="color: rgba(0, 128, 128, 1)">12</span> <span style="color: rgba(0, 0, 0, 1)"> }
</span><span style="color: rgba(0, 128, 128, 1)">13</span> <span style="color: rgba(0, 0, 0, 1)"> }
</span><span style="color: rgba(0, 128, 128, 1)">14</span>
<span style="color: rgba(0, 128, 128, 1)">15</span> <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">勾选、取消勾选某一个todo的回调</span>
<span style="color: rgba(0, 128, 128, 1)">16</span> <strong>handleCheck</strong> = (id)=><span style="color: rgba(0, 0, 0, 1)">{
</span><span style="color: rgba(0, 128, 128, 1)">17</span> <span style="color: rgba(0, 0, 255, 1)">return</span> (<strong>event</strong>)=><span style="color: rgba(0, 0, 0, 1)">{
</span><span style="color: rgba(0, 128, 128, 1)">18</span> <strong><span style="color: rgba(0, 0, 255, 1)">this</span><span style="color: rgba(0, 0, 0, 1)">.props.updateTodo(id,event.target.checked)
</span></strong><span style="color: rgba(0, 128, 128, 1)">19</span> <span style="color: rgba(0, 0, 0, 1)"> }
</span><span style="color: rgba(0, 128, 128, 1)">20</span> <span style="color: rgba(0, 0, 0, 1)"> }
</span><span style="color: rgba(0, 128, 128, 1)">21</span>
<span style="color: rgba(0, 128, 128, 1)">22</span> <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">删除一个todo的回调</span>
<span style="color: rgba(0, 128, 128, 1)">23</span> <strong>handleDelete</strong> = (id)=><span style="color: rgba(0, 0, 0, 1)">{
</span><span style="color: rgba(0, 128, 128, 1)">24</span> <span style="color: rgba(0, 0, 255, 1)">if</span>(window.confirm('确定删除吗?'<span style="color: rgba(0, 0, 0, 1)">)){
</span><span style="color: rgba(0, 128, 128, 1)">25</span> <strong><span style="color: rgba(0, 0, 255, 1)">this</span><span style="color: rgba(0, 0, 0, 1)">.props.deleteTodo(id)
</span></strong><span style="color: rgba(0, 128, 128, 1)">26</span> <span style="color: rgba(0, 0, 0, 1)"> }
</span><span style="color: rgba(0, 128, 128, 1)">27</span> <span style="color: rgba(0, 0, 0, 1)"> }
</span><span style="color: rgba(0, 128, 128, 1)">28</span>
<span style="color: rgba(0, 128, 128, 1)">29</span>
<span style="color: rgba(0, 128, 128, 1)">30</span> <span style="color: rgba(0, 0, 0, 1)"> render() {
</span><span style="color: rgba(0, 128, 128, 1)">31</span> const {id,name,done} = <span style="color: rgba(0, 0, 255, 1)">this</span><span style="color: rgba(0, 0, 0, 1)">.props
</span><span style="color: rgba(0, 128, 128, 1)">32</span> const {mouse} = <span style="color: rgba(0, 0, 255, 1)">this</span><span style="color: rgba(0, 0, 0, 1)">.state
</span><span style="color: rgba(0, 128, 128, 1)">33</span> <span style="color: rgba(0, 0, 255, 1)">return</span><span style="color: rgba(0, 0, 0, 1)"> (
</span><span style="color: rgba(0, 128, 128, 1)">34</span> <li style={{backgroundColor:mouse ? '#ddd' : 'white'}} <strong>onMouseEnter={<span style="color: rgba(0, 0, 255, 1)">this</span>.handleMouse(<span style="color: rgba(0, 0, 255, 1)">true</span>)} onMouseLeave={<span style="color: rgba(0, 0, 255, 1)">this</span>.handleMouse(<span style="color: rgba(0, 0, 255, 1)">false</span>)}</strong>>
<span style="color: rgba(0, 128, 128, 1)">35</span> <label>
<span style="color: rgba(0, 128, 128, 1)">36</span> <input type="checkbox" <strong>checked={done} onChange={<span style="color: rgba(0, 0, 255, 1)">this</span>.handleCheck(id)}</strong>/>
<span style="color: rgba(0, 128, 128, 1)">37</span> <span>{name}</span>
<span style="color: rgba(0, 128, 128, 1)">38</span> </label>
<span style="color: rgba(0, 128, 128, 1)">39</span> <button <strong>onClick={()=> <span style="color: rgba(0, 0, 255, 1)">this</span>.handleDelete(id) }</strong> className="btn btn-danger" style={{display:mouse?'block':'none'}}>删除</button>
<span style="color: rgba(0, 128, 128, 1)">40</span> </li>
<span style="color: rgba(0, 128, 128, 1)">41</span> <span style="color: rgba(0, 0, 0, 1)"> )
</span><span style="color: rgba(0, 128, 128, 1)">42</span> <span style="color: rgba(0, 0, 0, 1)"> }
</span><span style="color: rgba(0, 128, 128, 1)">43</span> }</pre>
</div>
<p><strong>3. 效果</strong></p>
<p><img src="https://img2020.cnblogs.com/blog/1217233/202104/1217233-20210421202857187-2042384663.png"></p>
<p> </p><br><br>
来源:https://www.cnblogs.com/le220/p/14686814.html
頁:
[1]