React的简书仿写项目肯定好多人都实践过了,因为这是慕课特别有名的Dell Lee老师的课程,2021学习这个课程算比较老了。但是涉及到的react的知识点和思想肯定是相通的,对于没有项目经验的我是足够的。
其实还有两个页面是空白的,写文章页面和作者的个人主页。但是我着急想试试打包和部署,然后今天就部署到服务器上了。
下面是效果图
学习过程中笔记存档:
第一页:
- react-create-app是react的官方脚手架工具,帮助我们构建前端工程目录。
- npm是node的包管理工具
- node-modules:项目依赖的第三方的包
- public -favico.ico网页图标
- src存放了项目所有的源代码。index.js是入口文件。可以使用import 方式导入css文件
- registerServiceWorker可以使页面存储在浏览器上,使得用户在断网的情况下也能访问页面。
- mainfest.json里面定义了当用户将网页作为app时如何西安市图标,如何跳转等。
- 组件具体渲染的内容是由render函数返回的结果所决定的。在js文件中直接写标签就是jsx,还可以使用自己定义的标签(组件)
- 在jsx语法中如果要使用自己定义的标签(组件),组件名必须以大写字母开头。一个组件的render函数返回的内容必须包裹在一个标签中。可以使用Fragment标签解决返回多个组件的问题。
第二页
1 . React中的响应式设计思想和事件绑定
不要操作DOM,关注数据。数据变化react替我们修改dom
数据要定义在状态state中,this.state={}用来存储数据
如果想改变state中的数据,React给每个组件提供了一个方法:this.setState()。
2 . 事件绑定记得修改this变更
3… JSX细节语法补充:样式定义不再使用class而是className。dangerouslySetInnerHTML设置不对标 签转义(可能造成XSS攻击)
4 组件的拆分和传值。
子组件如何调用父组件的方法,需要父组件将方法传给子组件。父组件给子组件传值使用属性,子组件给父组件传值使用父组件传递的方法
5. 单项数据流。
父组件可以向子组件传值,子组件只能使用,不能改变,如果要改变只能调用父组件传递过来的方法进行操作(还是父组件自己改变的)
6.react只是视图层操作,还需要数据层框架flux,输入-检查输出是否正确
7.函数式编程:维护容易,可以将函数拆分各司其职,有利于自动化测试,面向测试的开发流程
第三页
- Props,State与Render函数
- 当组件的state或者props发生改变时,render函数会重新执行;父组件的render重新执行时,子组件的render也会重新执行。
- 什么是虚拟DOM?
一:State:数据
二:JSX:模板
三:数据+模板 结合生成真实DOM,显示
四:state改变
五:数据+模板结合生成真实DOM,替换原始DOM
缺陷:第一次生成完整DOM片段,第二次同样生成全部替换,非常耗性能。
第一次修改:在第五步不生成真实DOM而是新旧对比找差异,只替换有差异的DOM
仍然有缺陷
五:生成真实DOM 不需要。而是生成虚拟DOM(JS对象)用来描述真实DOM(用js生成就是对象很快,用js生成DOM对象很耗性能)
五:state发生变化
六:生成新的虚拟DOM
七:比较原始虚拟DOM和新的虚拟DOM的区别
八:更新有差异的DOM
4.什么时候虚拟DOM发生改变?
数据改变的时候。当state或者props发生改变,说到底还是父的state发生改变,也就是setState被调用的时候。数据才发生变化,虚拟DOM的比较才发生
第五页
1.setState方法是异步的,这样做是为了提高底层性能。假设连续三次调用setState修改数据,react将 三次修改一起执行然后生成虚拟DOM,再比较而不是修改一次执行一次- Diff算法:同级比较,算法简单,速度快。如果当前层DOM不一样,下面层不再比较,直接替换。。虚拟DOM的比较有key值更容易确定虚DOM树之间新旧节点,否则循环的时候只是通过两层循环比较。有了key值比较新旧节点的时候只需看key值,相同key值的两个节点的差异,但是有个前提是新旧DOM树上同一个节点的key值要一样。这也是为什么循环时不要用index作为key值。比如逆序删除数组中元素的时候,后面的元素的index值会改变,也就是同一个节点的key值发生改变,即使这个节点并没有改变。
第四页
- React的生命周期。生命周期函数是指在某一时刻组件会自动执行调用的函数。render函数会在state或props发生改变时重新自动执行。所以render就是一个生命周期函数。constructor也满足生命周期函数的定义,组件创建时调用。
- 对于一个react来说有几个过程
Initialization 初始化 setup props and state
Mounting 挂载 componentWillMount 组件即将被挂载到页面上时执行。(执行一次,更新不会执行)
render 渲染页面
componentDidMount组件挂载到页面上之后执行。(执行一次,更新不会执行)
Updation 更新 props或state发生改变
componentWillReceiveProps
shouldComponentUpdate
componentWillUpdate
render
componentDidUpdate
shouldComponentUpdate函数返回一个boolean询问:你的组件要更新吗?false时不更新组件,true更新组件,返回false下边流程不执行。
componentWillReceiveProps函数执行需要两个条件:1.一个组件从父组件接收参数;2.只要父组件的render函数被重新执行,子组件收到的值第二次发生变化后触发。
Unmounting
componentWillUnmounted在组件从页面上剔除的时候执行。
第五页
1.react生命周期函数非常重要。生命周期函数属于每个组件。出了render函数,别的生命周期函数都可以省略(Component中已经内置)
2.react性能提升的几个点
一、this作用域的改变统一放到constructor函数中
二、利用shouldComponentUpdate避免不必要的render渲染
三、setState是异步函数,可以将多次更新结合成一次来做,降低虚拟dom的对比频率
四、同层比对虚拟dom
第六页
1.React是轻量级视图层框架,要配合数据层框架Redux使用。将组件中的数据存放在一个公共空间store,有组件更新数据时,别的组件感知到然后从store中获取数据。
2.Redux=Reducer+Flux
3.antd Ant Design of React antd开发后台管理页面非常好用。
npm install antd --save 别忘了引入样式:import ‘antd/dist/antd.css’
第七页
Redux知识点复习。Redux设计和使用的三项原则
一、store是唯一的。
二、只有store能改变自己的内容。reducer拿到store之前的数据,根据传入的改变,生成新的数据,把新数据返回给store,store拿到新数据自己更新
三、Reducer必须是纯函数。给定固定的输入,就一定有固定的输出,而且不会有任何副作用。当一个函数有setTimeout,ajax请求以及和日期相关的内容都不再是一个纯函数。
Redux中的核心API:
createStore:创建store
store.dispatch:派发action
store.getState:帮助获取state中的内容
store.subscribe:订阅store的改变
Redux的中间件(这里指的是action和store的中间件)
redux-logger可以记录action每次派发的日志,saga解决异步问题。
第八页
创建Redux中的store
- 安装 npm install redux --save
- reducerjs export default (state,action={return state})
- import {createStore } from ‘redux’
- const store =createStore();
- import reducer from … store =createStore(reducer)
React-redux的使用
- npm install react-redux
- import {Provider} from ‘react-redux’
- 第一个核心API 提供器连接了store。provider里面的组件都有能力获取store中的数据
- 第二个核心API Connect Connect导入时要作为一个方法导入而不是一个模块,使用解构赋值。
第九页
1.UI组件和容器组件。当我们的组件中只有一个render函数时,就可以用一个无状态组件来定义这个组件。优势:性能高,就是一个函数。UI组件可以定义为无状态组件。
2.使用Redux-thunk中间件实现ajax数据请求。