目录 | 课程名 | 备注 |
---|---|---|
《react16.4快速上手》 | ||
《React16.4 开发简书项目 从零基础入门到实战》 | ||
《react全家桶+and共享单车后台管理系统开发》 |
《imooc-react16.4快速上手》 |
地址:https://www.imooc.com/learn/1023
一、react fiber指的是react16之后的版本。
二、react生命周期
1、componentWillMount:在渲染前调用。
2、componentDidMount:在第一次渲染后调用,组件已经生成了对应的DOM结构。
3、componentWillReceiveProps:在组件接收到一个新的 prop (更新后)时被调用。这个方法在初始化render时不会被调用。
componentWillReceiveProps(newProps) {}
4、shouldComponentUpdate:返回一个布尔值。在组件接收到新的props或者state时被调用。在初始化时或者使用forceUpdate时不被调用。可以在你确认不需要更新组件时使用。
5、componentWillUpdate:在组件接收到新的props或者state但还没有render时被调用。在初始化时不会被调用。
6、componentDidUpate:在组件完成更新后立即调用。在初始化时不会被调用。
7、componentWillUnmount:在组件从 DOM 中移除之前立刻被调用。
8、getDefaultProps
9、getInitialState
10、render
一、react开发环境
1、node
2、官网-create react app
(1)npx create-react-app todlist
(2)cd todolist
(3)npm start
一、registerServiceWorker是pwa的概念,单页面应用。
一、react中,大写字母开头都是组件
二、react组件中,必须有个函数叫render,这个函数负责组件显示的内容。
三、reactDOM可以帮我们把react组件渲染到dom节点上。
四、类继承React.Component,就成了react组件。
五、jsx的{}中可以写js表达式(如1+2),而不是js语句(如if() {})。
一、组件被创建的瞬间,constructor()会被自动执行,super()做一些初始化。
一、如果要改变state中的list,建议拷贝一个出来操作。
1、比较容易发现错误,调试错误。
2、react升级后性能会比直接改变list好一些。
3、state状态强调imuutable(不可变的)。
一、父子组件传参
1、父组件通过属性向子组件传递参数
2、子组件通过props接受父组件传递过来的参数
// 将输入框的值显示在搜索历史列表中
handleBtnClick() {
this.setState({
list: [...this.state.list, this.state.inputValue],
inputValue: ''
});
}
一、父子组件通信
1、子组件如果想和父组件通信,子组件要调用父组件传递过来的方法
一、如果onClick直接写this.handleDelete.bind(this)性能没那么好,还是在constructor里中写this.handleDelete = this.handleDelete.bind(this)好一些。
handleDelete(index) {
const list = [...this.state.list];
list.splice(index, 1);
this.setState({list});
}
一、jsx样式
1、style={{background: ‘red’}}
最外层的{}表示这是js表达式,里面的{}表示是一个对象。
2、设置样式用className,不要用class,class是js中类的关键词(保留字)。
二、render()需要用最外层元素包裹,如果用div,样式不好布局的时候,可以用React.Fragment
,这时候就不会有多余的div
render() {
return (
测试
- 单独项
)
}
20190510-20190704:《imooc-React16.4 开发简书项目 从零基础入门到实战》 |
(aSuncat:前3章到3-03为止,讲的全是《imooc-react16.4快速上手》的内容,如果已经看过这门过程的人,就没必要看。)
一、课程内容
1、基础内容:环境搭建-> 基础语法 -> 原理进阶 -> 动画 -> redux -> redux进阶
2、实战项目:环境搭建 -> header -> 首页 -> 详情页 -> 登陆校验 -> 上线
二、课程涉及到的react技术点
1、create-react-app、组件化思维、jsx、开发调试工具、虚拟dom、声明周期、React-transition-group、redux、antd、ui/ 容器组件、无状态组件、Redux-thunk(redux中间件)、Redux-saga(redux中间件)、Styled-components(css样式编码,避免组件之间样式的污染)、immutable.js(避免数据的误操作)、redux-immutable(redux中间件)、axios(ajax请求发送)
一、脚手架工具是node包文件,都有package.json文件,有项目名称、指令等供自己调用。
二、目录文件
1、package.json:
"start": "react-scripts start"
,通过react-scripts工具启动。
2、.gitignore
不想传到git上的文件。
3、public/ index.html
提高代码的健壮性
4、manifest.json
PWA serviceWorker,如果当app使用,快捷方式的图标,定义网址,主题
5、App.test.js:
自动化测试文件
6、src/ index.js 项目入口文件
三、pwa: progressive web application
RegisterServiceWorker:与pwa有关
1、reactDom是一个第三方模块,有个render方法,能将组件挂载到某一个dom节点下。
2、public/ index.html是工程的html模板
3、只要有jsx语法,想要在react中使用jsx,就得引入React
import React from 'react'
一、react中改变state的值,只能用setState,不能通过改变state的引用来改变值,如,得用this.setState({inputVal: ''})
,而不能是this.state.inputVal = e.target.value
;
一、react:state不变
1、immutable
2、state不允许我们做任何的改变,如果修改了state,后续优化的时候会有问题。
一、如果是在jsx中写注释,
1、一行:{/这是注释/},注意要用{},得用/**/,不能用//
2、多行
{
// 下面是一个input框
}
二、含带html标签的文字
1、
就能得到直接显示html
2、如果直接用
就只能得到直接显示html
三、html中,label的作用是扩大点击的区域。
这样与jsx中的for冲突,会报错,应该写成
一、es6中,({inputValue: e.target.value})最外层的()有return的意思
1、this.setState({inputValue: e.target.value})
可以写成
this.setState(() => ({inputValue: e.target.value}))
,但是这样是异步的,赋值会有问题,所以可以用
const value = e.target.value; this.setState(() => ({inputValue: value}))
2、可以避免不小心改变state的状态
this.setState((prevState) => ({
list: [...prevState.list, prevState.inputValue],
inputValue: ''
}))
一、
1、命令式编程:直接操作dom,如原生js,jquery
2、声明式开发:面向数据,数据构建完成之后,react可以自动根据数据来更新dom。可以与其他框架共存。如react
二、react
1、声明式开发。
2、可以与其他框架共存。react与其他框架的代码要互不影响。
3、组件化。
4、单向数据流。父组件向子组件传值,这个值子组件可以使用,但是不能更改。
为了使测试更方便,不容易遇到坑。
5、视图层框架。react只负责数据和页面渲染方面的问题。flux,redux等数据层框架
6、函数式编程。如果代码里都是一些函数的话,给前端自动化测试带来了很大的便利。
三、面向测试开发流程,自动化测试
一、PropTypes作为属性接收的强校验
import PropTypes from 'prop-types'
TodoItem.propTypes = {
test: PropTypes.string.isRequired, // 如果没有传,则不会校验,代码就不会报错
test: PropTypes.string.isRequired, // 如果没有传,会报错
content: PropTypes.string,
content: PropeTypes.arrayOf(PropTypes.number, PropeTypes.string), // content是数组,数组里的项可以是数字, 也可以是字符串
content: PropeTypes.oneOfType([PropTypes.number, PropeTypes.string]), // content可以是数字,或者是字符串
deleteItem: PropTypes.func,
index: PropTypes.number,
}
二、DefaultProps
TodoItem.defaultProps = {
test: 'hello world',
}
一、当组件的state或者props发生改变,它自己的render函数就会重新执行一次。
二、当父组件的render函数被运行时,它的子组件的render都会被执行一次。
一、
1、实现
(1)state 数据
(2)jsx模板
(3)数据+ 模板结合,生成真实的dom,来显示
(4)state发生改变
(5)数据+模板结合,生成真实的dom,替换原始的dom
2、缺陷
(1)第一次生成了一个完整的dom片段。
第二次生成了一个完整的dom片段。
第二次的dom替换第一次的dom,非常耗性能。
3、改进
(1)state 数据
(2)jsx模板
(3)数据+ 模板结合,生成真实的dom,来显示
(4)state发生改变
(5)数据+模板结合,生成真实的dom,并不直接替换原始的dom。
(6)新的dom和原始的dom做比对,找差异。
(7)找出Input框发生了变化
(8)只用新的dom中的input元素,替换掉老的dom中的input元素。
4、第二次改进
(1)state 数据
(2)jsx模板
(3)数据+ 模板结合,生成真实的dom,来显示
(4)生成虚拟dom(虚拟dom就是一个js对象,用它来描述真实dom)
['div', {id: 'abc'}, ['span', {}, 'hello world']]
(5)state发生变化
(6)数据+ 模板,生成新的虚拟dom(极大得提升了性能)
(7)比较原始虚拟dom和新的虚拟dom的区别,找到区别是span中的内容
(8)直接操作dom,改变span中的内容
5、react
(1)state 数据
(2)jsx模板
(3)数据+ 模板结合,生成虚拟dom,来显示
(4)用虚拟dom的结构生成真实的dom,来显示
(5)state发生变化
(6)数据+ 模板,生成新的虚拟dom(极大得提升了性能)
(7)比较原始虚拟dom和新的虚拟dom的区别,找到区别是span中的内容
(8)直接操作dom,改变span中的内容
二、js创建js对象很简单,但是如果创建一个dom,就需要调用一个webApplication级别的api
一、jsx ->createElement -> 虚拟dom( js对象) -> 真实的dom
二、优点
1、性能提升了。
2、它使得跨端应用得以实现。react native
一、react底层会用到diff算法,diff, difference
二、setState设计成异步,是为了提高性能。
三、diff算法,同级比对,
优点:算法简单,比对速度非常快。
缺点:会造成一些dom节点渲染的浪费。
但是大大减少比对性能消耗。
四、循环最好不要用index作为Key值,因为这样就没法保证原来的key值与真正的数据一一对应。
1、['勤', '奋', '向', '上']
这时候的key与value对应关系
0 - 勤, 1 - 奋, 2 - 向, 3 - 上。
2、“向”前加入“好”
0 - 勤, 1 - 奋, 2 - 好,3 - 向, 4 - 上。
2不再对应向,3不再对应上。key值就不能与value建立起稳定正确的关系。
五、引入key值
1、提高虚拟dom比对性能。
2、key值要保持稳定。项目中,能不用index作为key值,就不要用。因为index值不稳定。
一、如果要操作dom,不应该在setState()后执行,需要放在setState的第二个参数中。
this.setState((prevState) => ({
list: [...prevState.list, prevState.inputValue],
inputValue: ''
}), () => {
console.log(this.ul.querySelectorAll('div'))
})
二、尽量避免使用ref,如果要使用,注意setState是异步的
ref={(input) => this.input = input}
一、生命周期函数指在某一个时刻组件会自动执行的函数
二、
1、Initialization:初始化
setup props and state
2、mounting:挂载
componentWillMount -> render -> componentDidMount
(1)componentWillMount:在组件即将被挂载到页面的时刻自动执行
(2)render
①子组件数据发生变化
②父组件render发生改变
(3)componentDidMount:组件被挂载到页面之后,自动执行
3、updation
(1)props
①componentWillReceiveProps:
条件:一个组件要从父组件接收参数;如果这个组件第一次存在于父组件中,不会执行;如果这个组件之前已经存在于父组件中,才会执行
执行条件:只要父组件的render函数被重新执行了,子组件的这个生命周期函数就会被执行
②shouldComponentUpdate:需要有返回的布尔值,return true
,或者return false
如果返回true,则继续进行。
③componentWillUpdate
如果shouldComponentUpdate返回true,它才执行;如果返回false,这个函数就不会执行了。
④render
⑤componentDidUpdate
(2)states
①shouldComponentUpdate
②componentWillUpdate:如果sholdCoponentUpdate返回true,才执行。
③render
④componentDidUpdate
4、Unmounting
componentWillUnmount:当这个组件即将被从页面中剔除的时候,会被执行
三、生命周期
(1)componentWillMount
(2)render
(3)componentDidMount
(4)componentWillReceiveProps
(5)componentWillUpdate
(6)componentDidUpdate
(7)componentWillUnmount
一、所有的生命周期都可以不存在,但是render()这个生命周期必须有
react的component默认其他所有生命周期函数,但是没有默认render,所以如果自己写,render必须有
二、shouldComponentUpdate,提升了组件的性能,可以避免组件产生不必要的render
1、如果return false,当父组件数据发生改变时,子组件并不会发生渲染
2、
shouldComponentUpdate(nextProps, nextState) {
if (nextProps.content !== this.props.content) {
return true;
} else {
return false;
}
}
三、一般ajax请求放在componentDidMount
1、如果ajax放在render中,容易死循环。因为render会重复执行
2、如果放在coomponentWillmount中,react也是可以的。但是如果是在react native,服务器端同构中,就容易发生错误。
四、发送ajax请求
1、终端输入:yarn add axios
2、
axios.get('api/todolist')
.then(() => {})
.catch(() => {})
一、桌面创建文件
1、cd Desktop
2、touch todolist.json
["dell", "lee", "imooc"]
二、charles
1、tools -map local
2、map from:http localhost 3000 /api/todolist
3、local from:本地的todolist.json文件
三、
this.setState(() => {
return {
list: res.data
}
})
可以优化写成
this.setState(() => ({
list: [...res.data]
}))
一、动画模块:react-transition-group模块
二、安装使用
1、npm install react-transition-group --save
2、
(1)js文件
{el.style.color='blue'}}
apper={true}
>
①apper={true},第一次显示的时候就有动画,需要有.fade-appear,.fade-appear-active样式
②入场动画执行到第一帧:onEntering
(2)css文件
.fade-enter, .fade-appear {}
.fade-enter-active, .fade-appear-active{}
.fade-enter-done{}
.fade-exit-enter{}
.fade-exit-active{}
.fade-exit-done{}
三、react-transition-group一般是用cssTransition,transition是cssTransition解决不了时用的
一、react-transition-group的transitionGroup可以让多个组件有动画效果
import {CSSTransition, TransitoinGoup} from 'react-transition-group'
this.state.list.map((item,index) => {
return (
{el.style.color='blue'}}
apper={true}
key={index}
>
item
(1)CSSTransition没有in属性
(2)循环列表的key放到外层标签,不放div中
一、react是一个轻量级的视图层框架
二、需要配套数据层框架和react配合使用,全球较好的数据层框架:redux
三、redux = reducer + flux(官网推出的最原始的数据层框架,现已过时)
一、antd:react基础组件库
1、antd官网,开始使用,https://ant.design/docs/react/introduce-cn
2、 npm i antd --save
一、
npm i redux --save
一、store.subscribe()
二、react要改变store里的数据,先要去派发一个action,action会通过dispatch方法传递给store,store再把之前的数据和action转发给reducer,reducer是一个函数,它接收到了state和action之后,做一些处理之后,会返回一个新的state给到sote,store用这个新的state替换到之前的store里的数据,store数据发生改变的时候,react组件知道store的数据发生了改变,这个时候会从store重新取数据,更新组件内容,页面就跟着发生变化了。
一、如果写成actionTypes.js,如果变量名写错,则控制台会报错。如果不放在actionTypes.js中,直接写个字符串,是不会报异常的,出了错误会非常难调。
一、store必须是唯一的
二、只有store能够改变自己的内容
1、reducer可以接收state,但是绝不能修改state
三、reducer必须是纯函数
1、纯函数指的是,给定固定的输入,就一定会有固定的输出,而且不会有任何副作用。
(1)如果有setTimeout, ajax请求,new Date(),等,就不是纯函数了。
newState.inputValue = new Date();
就不是纯函数了。
(2)state.inputValue = action.value;
就是有副作用
四、store相关
createStore
store.dispatch
store.getState
store.subscribe
一、ui组件负责页面的渲染
容器组件负责页面的逻辑
二、视频中点击删除,视频中的写法index其实得到的是e,从上往下删除看起来不会报错,但是代码逻辑错误,应该用闭包
renderItem={(item, index) => {
return (
{this.props.handleDeleteClick(index)}}>
{item}
)}}
一、无状态组件,无状态组件的性能会比较高;
1、如果组件是ui组件,只负责页面的渲染,只有render函数,推荐使用无状态组件
2、js生成的类,里面会有生命周期等,性能不如无状态组件
// 无状态组件
const TodoListUI = (props) => {}
// 类
class TodoListUI extends Component {}
一、git搜索redux-thunk
1、npm install redux-thunk --save
2、引入中间件
import { applyMiddleware } from 'redux';
import thunk from 'redux-thunk';
const store = createStore(
rootReduce,
applyMiddleware(thunk)
)
二、通过redux创建store的时候,要用中间件
三、redux-thunk是redux的中间件,不是react的中间件。
四、applyMiddleware([redux-thunk, window.__REDUX_DEVTOOLS_EXTENSION__ && window.__REDUX_DEVTOOLS_EXTENSION__()])
会出错
1、解决
(1)redux-devtools-extension
(2)advanced store setup
(3)创建了composeEnhancers
(4)
const composeEnhancers = window.__REDUX_DEVTOOLS_EXTENSION__ && window.__REDUX_DEVTOOLS_EXTENSION__();
const enhancer = composeEnhancers(
applyMiddleware([thunk])
)
const store = createStore(
reducer, /* preloadedState, */
enhancer
);
五、调用store.dispatch,把action放到store的时候,这个action就会被自动执行,这个action就是actionCreators.js里的函数(异步请求).
六、actionCreators.js里,函数里能接收到store的dispatch方法
export const getTodoList = () => { return (dispatch) => {} }
七、只有用了redux-thunk,action才可以返回一个函数,不然只能返回一个对象。
一、中间件指的是action和store之间
二、dispatch,如果是对象,就直接把对象传给action,如果是函数,就等函数执行完之后传给action
三、中间件
1、redux-thunk,是把ajax放到action去操作
2、redux-saga,是把ajax单独拿出来处理。
3、redux-logger,是根据dispatch来对每次操作进行console.log()
一、只有redux才有action和store的概念,而不是react的
二、可以用redux-saga完全代替redux-thunk
三、安装及使用redux-saga
1、npm install redux-saga --save
2、store/index.js
import { createStore, applyMiddleware, compose } from 'redux';
import reducer from './reducer';
// import thunk from 'redux-thunk';
import createSagaMiddleware from 'redux-saga';
import sagas from './sagas';
const composeEnhancers = window.__REDUX_DEVTOOLS_EXTENSION__ && window.__REDUX_DEVTOOLS_EXTENSION__();
// const middleware = [thunk];
const sagaMiddleware = createSagaMiddleware();
const enhancer = compose(applyMiddleware(sagaMiddleware), composeEnhancers);
const store = createStore(
reducer, /* preloadedState, */
enhancer
);
sagaMiddleware.run(sagas);
export default store;
一、有了redux-saga,reducer可以接收action,sagas也可以接收action
二、sagas.js中,用put代替store.dispatch(action)
三、generator函数里不要用promise形式了
const res = yield axios.get('http://localhost:3000/mock/list');
const action = initListAction(res.data);
yield put(action);
代替
axios.get('http://localhost:3000/mock/list').then((res) => {
const data = res.data;
const action = initListAction(data);
put(action);
})
一、(提供器) 连接store,把store提供给内部所有组件了。
二、mapDispatchToProps是把store.dispatch挂载到props上。
三、todolist是一个Ui组件,connect将ui组件和业务逻辑相结合,返回的内容是一个容器组件。
1、容器组件包括数据,派发之类的东西
一、npm安装失败,网络问题等的解决方案有以下2种:
1、cnpm
2、手机切换到移动网络,开个热点,电脑连接到热点
二、styled-components,对css样式进行管理。
1、npm install --save styled-components
三、aSuncat:eslint
1、
npm install --save-dev eslint babel-eslint eslint-config-airbnb eslint-plugin-import eslint-plugin-react eslint-plugin-jsx-a11y
babel-eslint:项目中需要用到es2015规范
eslint-config-airbnb : 配置一些 eslint rules 的规范
eslint-plugin-import :在使用 import 的时候,一些 rules 规范
eslint-plugin-react : 一些 react 的 eslint 的 rules 规范
eslint-plugin-jsx-a11y: 一些 jsx 的 rules 规范
2、.eslintrc
{
// 环境
"env": {
"browser": true,
"commonjs": true,
"es6": true,
"node": true
},
// 使用的扩展库
"extends": "airbnb",
// 解析器用于解析代码
"parser": "babel-eslint",
// 解析器配置
"parserOptions": {
"ecmaVersion": 8,
"sourceType": "module",
"ecmaFeatures": {
"jsx": true
}
},
// 第三方插件
"plugins": [
"react"
],
// 规则
"rules": {
"eol-last": 0, // 在非空文件的末尾至少执行一个换行符(或不存在)
"func-names": 0,
"max-len": 0, // 代码最大行长度,0-不校验
"no-console": 0, // 禁止调用console对象的方法
"no-underscore-dangle": 0, // 不允许在标识符中使用悬空下划线
"no-param-reassign": 0,
"no-plusplus": 0,
"no-unused-expressions": 0,
"no-unused-vars": 0,
"object-curly-newline": 0, //在对象文字或解构赋值的大括号内强制执行一致的换行符
"semi": [2, "always"], // 语块结尾要加分号
"import/prefer-default-export": 0, // 只有一个export时,使用default
"jsx-a11y/anchor-has-content": 0, // a标签需要有内容
"jsx-a11y/click-events-have-key-events": 0, // 不能给非绑定元素(如:li )绑定事件问题
"jsx-a11y/no-static-element-interactions": 0, // 静态html元素(非Button)的 onClick 事件需要至少一个键盘事件
"react/destructuring-assignment": 0,
"react/jsx-filename-extension": [1, { // 允许使用jsx的文件扩展名
"extensions": [".js", ".jsx"] // 允许使用jsx的文件扩展名:.js 和.jsx 文件
}],
"react/jsx-one-expression-per-line": 0,
"react/no-array-index-key": 0, // 禁止使用数组的 index 作为 key
"react/no-danger": 0, // 禁止在使用了 dangerouslySetInnerHTML 的组建内添加 children
"react/prefer-stateless-function": 0, // 如果组件是一个无状态组件,推荐使用正常函数,而不是用类class
"react/prop-types": 0, // 必须定义props的type
"react/self-closing-comp": 0 // 当标签没有子元素的时候,始终使用自闭合的标签
}
}
3、package.json的scripts
"scripts": {
"start": "react-scripts start",
"build": "react-scripts build",
"test": "react-scripts test",
"eject": "react-scripts eject"
},
改成:
"scripts": {
"start": "PORT=3002 react-scripts start",
"dev": "npm run lint && npm run start",
"build": "react-scripts build",
"test": "react-scripts test",
"eject": "react-scripts eject",
"lint": "eslint --ext .js --ext .jsx src",
"lint-fix": "eslint --fix --ext .js --fix --ext .jsx src"
},
(1)"lint": "eslint --ext .js --ext .jsx src",
// lint:检查代码是否符合eslint规则
(2)"lint-fix": "eslint --fix --ext .js --fix --ext .jsx src"
// lint-fix: 修复不符合eslint规则的代码
4、关闭eslint检查
(1)关闭当前文件eslint检查
/*eslint-disable*/
function test() {
return true
}
(2)关闭某一行eslint检查
// eslint-disable-next-line
(3)调整eslint规则
/* eslint no-console:"error"*/
console.log('test');
5、如果使用了git,可以通过pre-commit钩子在每次提交前检测
(1)npm install --save-dev pre-commit
(2)
'pre-commit': [
''lint
]
四、通过terminal开启了一个端口号为3002的项目,找不到退出的出口,手动关掉terminal也不行,解决方案,terminal输入
pkill -a Terminal
五、视频中的injectGlobal这个api已经被弃用,应该用createGlobalStyle
六、css Tools的reset css,粘贴到style.js中
/* http://meyerweb.com/eric/tools/css/reset/
v2.0 | 20110126
License: none (public domain)
*/
html, body, div, span, applet, object, iframe,
h1, h2, h3, h4, h5, h6, p, blockquote, pre,
a, abbr, acronym, address, big, cite, code,
del, dfn, em, img, ins, kbd, q, s, samp,
small, strike, strong, sub, sup, tt, var,
b, u, i, center,
dl, dt, dd, ol, ul, li,
fieldset, form, label, legend,
table, caption, tbody, tfoot, thead, tr, th, td,
article, aside, canvas, details, embed,
figure, figcaption, footer, header, hgroup,
menu, nav, output, ruby, section, summary,
time, mark, audio, video {
margin: 0;
padding: 0;
border: 0;
font-size: 100%;
font: inherit;
vertical-align: baseline;
}
/* HTML5 display-role reset for older browsers */
article, aside, details, figcaption, figure,
footer, header, hgroup, menu, nav, section {
display: block;
}
body {
line-height: 1;
}
ol, ul {
list-style: none;
}
blockquote, q {
quotes: none;
}
blockquote:before, blockquote:after,
q:before, q:after {
content: '';
content: none;
}
table {
border-collapse: collapse;
border-spacing: 0;
}
一、aSuncat:不喜欢用css封装成组件使用,所以弃用styled-components,用sass写样式。
二、sass
1、npm i --save node-sass
一、阿里图标库:https://www.iconfont.cn
创建简书的图标库
一、redux引入combineReducers,将多个reducer组合在一起。
一、immutable.js
1、immutable对象,不可变更的对象
2、npm i --save immutable
3、通过fromJS将js对象转换成immutable对象
4、immutable对象中获取某个属性,用get方法
state.header.get('focused')
5、immutable对象的set方法,会结合之前immutable对象的值,和设置的值,返回一个全新的对象。
一、redux-immutable
1、reducer.js
import { combineReducers } from 'redux-immutable';
redux有combineReducers方法,返回普通的对象: state,redux-immutable有combineReducers方法,返回immutable对象:state
2、header/ index.js中
focused: state.get('header').get('focused'),
可以获取到state(immutable对象)中的header(immutable对象)中的focused属性,也可以简写成下列方式
focused: state.getIn(['header', 'focused']),
及用getIn方法代替get方法。
一、react 只能兼容到ie8浏览器
一、api/headerList.json
1、工程目录下看是否有对应的路由
2、public下的是否有api,是否有headerList.json
1、npm install --save react-router-dom
2、
import { BrowserRouter, Route } from 'react-router-dom';
home} />
detail} />
(1)BrowserRouter代表的是一个路由
(2)Route代表的是一个个路由规则
一、List只是最外面的数组变成了immutable对象,用fromJS使得数组和数组里面的小对象都变成immutable对象。
一、组件通过connect与store产生连接,,只要store数据发生了改变,那么每个组件都会被重新渲染,每次都会执行一次render函数。
二、按需加载组件
1、每个组件写shouldComponentUpdate,就可以按需
2、immutable.js与PureComponent想结合,就会根据数据改变按需重新渲染。
三、react-router-dom是单页面应用路由,单页面应用只会加载一次html,f12 - network - doc ,能看到页面html渲染次数
1、解决:用Link代替a标签,
一、获取参数
1、动态路由获取参数
to={
/detail/KaTeX parse error: Expected 'EOF', got '}' at position 18: …tem.get('id')}`}̲` `}
一、按需加载组件:react-loadable
1、详情代码只有在进入详情时才会加载
2、以Detail为例,detail文件夹下新增loadable.js
import React from 'react';
import Loadable from 'react-loadable';
const LoadableComponent = Loadable({
loader: () => import('.'),
loading() {
return 正在加载;
},
});
export default () => ;
二、const { params } = this.props.match;
,如果不用withRouter,会获取不到这个参数。
三、export default connect(mapStateToProps, mapDispatchToProps)(withRouter(Detail));
1、withRouter,让Detail有能力获取到Router中所有参数和内容
一、16.4,飞起来componentWillUpdate, componentWillReceiveProps
20190722-:《imooc-react全家桶+and共享单车后台管理系统开发》 |
一、公共机制封装
1、axios请求插件封装
2、api封装
3、错误拦截
4、权限、菜单封装
5、日期、金额、手机号封装…
6、Loading、分页、Mock…
二、项目整体架构
1、核心库、中间件、公共机制封装
一、react介绍
1、facebook开源的一个Javascript库
2、react结合生态库构成一个MV框架
3、react特点
(1)Declarative(声明式编码)
(2)Component-Based(组件化编码)
(3)高效-高效的DOM Diff算法,最小化页面重绘。
(4)单向数据流
二、MV框架代表-只关注视图view层+数据层model
三、生态介绍
1、vue生态: vue + vue-router + vuex + axios + babel + webpack
2、react生态:react + react-router + redux + axios + babel + webpack
四、
1、编程式实现
需要以具体代码表达在哪里(where),做什么(what),如何实现(how)
2、声明式实现
只需要声明在哪里(where)做什么(what),而无需关心如何实现(how)
一、yarn
1、yarn是新一代包管理工具
2、yarn
(1)速度快
(2)安装版本统一、更安全
(3)更简洁的输出
(4)更好的语义化
3、如何使用yarn
(1)yarn init
,npm init
(2)yarn add
, npm install
(3)yarn remove
, npm uninstall
(4)yarn / yarn install
, npm i 或 npm install
二、学习任何一门语言,都需要先学习官网内容。
三、安装yarn
npm i -g yarn
四、App.js:项目根组件
index.js:项目入口
一、生命周期里的方法,本来就是自己这个类的实例。
一、ant design react和ant design pro有什么区别
ant design react是一套react组件库,而pro是使用了这套组件库的完整前端脚手架。