官方文档
Redux
- 以Ant Design Pro为例详解Redux、redux-saga、dva
- Redux React Redux
- Redux周边库源码解读之Redux
- Redux周边库源码解读之redux-thunk&redux-saga(1)
- Redux周边库源码解读之redux-thunk&redux-saga(2)
- umi+Dva学习总结
技能图谱
React
├ Create React App
├ React Router // react-router-dom
├ Redux
├ Mobx
├ hooks
├ fetch
└ proxyTrack
React 有哪些缺点
要使用 useCallback 处理那些我们本来就不需要关注的问题。
React hooks 天生就会浪费性能,而官方也说,每个简单的 obj/arr/func 使用 useMemo 和 useCallback 会浪费大量时间。
生命周期
未整理
- 分析 React 组件的渲染性能
- React
- 图解React原理
- 性能优化
- 第三方协同
- 高阶组件
- React测试
- Concurrent 模式
- eslint-plugin-react-hooks
-
- 应用中所有的状态都是以一个对象树的形式存储在一个单一的store中;
- 当你想要改变应用的中的状态时,你就要dispatch一个action,这也是唯一的改变state的方法;
- 通过编写reducer来维护状态,返回新的state,不直接修改原来数据;
- UI 组件交互操作; 调用 model 的 effect; 调用统一管理的 service 请求函数; 使用封装的 request.js 发送请求; 获取服务端返回; 然后调用 reducer 改变 state; 更新 model
API
Redux
- Redux
- Redux 入门教程(一):基本用法
- React×Redux——react-redux库connect()方法与Provider组件
- react-redux 之 connect 方法详解
- mapStateToProps,mapDispatchToProps的使用详解 ✓
- 三分钟,帮你从Redux的深渊解脱
Hooks
- React Hooks 案例详解( react 进阶必备)
- useEffect你真的会用吗?
- useEffect进阶指南(上)
- useEffect进阶指南(下)
- 关于useEffect的一切
- 你真的用对 useEffect 了吗?
- useEffect和useLayoutEffect的区别
- 深入理解 React useLayoutEffect 和 useEffect 的执行时机
- 一份完整的useEffect指南
- useCallback的使用背景 ✓
- 使用useEffect常见问题!
Demo
React
脚手架
使用脚手架(Toolchains): create-react-app
npx create-react-app react-typescript-mobx --typescript
cd react-typescript-mobx
npm start
默认入口文件 /src/index.js
基本用法
var HelloWorld = React.createElement(
'div',
{
className: 'shopping-list'
},
'Hello world!'
)
// 使用
ReactDOM.render(
HelloWorld,
document.getElementById('root')
);
// 或者
class App extend React.Component {
constructor() {
super();
this.state = {
value: null,
};
}
render() {
return (
<h1>{this.props.title}</h1>
)
}
}
// 函数组件
function Test() {
return (
<p>Hello world!</p>
);
}
// 使用
ReactDOM.render(
<App /><Test />,
document.getElementById('root')
);
JSX 的大括弧中可以写任意表达式
class -> className
tabindex -> tabIndex
有状态组件
根据我们已有的知识,更新 UI 唯一的方式是创建一个全新的元素,并将其传入 ReactDOM.render()。在实践中,大多数 React 应用只会调用一次 ReactDOM.render()。在下一个章节,我们将学习如何将这些代码封装到有状态组件中。
state 的更新可能是异步的。出于性能考虑,React 可能会把多个 setState() 调用合并成一个调用。因为 this.props 和 this.state 可能会异步更新,所以你不要依赖他们的值来更新下一个状态。
受控组件 & 非受控组件
绑定事件
onClick={this.handleClick} // 传入函数名,不带 ()
绑定 this
- 在构造函数中
this.handleClick = this.handleClick.bind(this)
- 实验性功能: public class fields 语法
handleClick = () => {}
- 调用时使用闭包
onClick={()=>this.handleClick()}
传参
<button onClick={(e) => this.deleteRow(id, e)}>Delete Row</button>
<button onClick={this.deleteRow.bind(this, id)}>Delete Row</button>
注意
key 不会传递给组件,props.key读不到,必须换名字。
如果一个map() 嵌套太多,就需要提取组件。
待梳理
textarea 使用 value 属性
select 使用 value 属性,value 支持数组
非受控组件?
在受控组件上指定 value 的属性可以防止用户更改输入?
Formik
数据请求 https://blog.csdn.net/ZYC88888/article/details/82531610
v16 以后不再使用 React.createClass()
ref={node => {a = node}}
React Router
npm install --save react-router-dom
所有组件都需要引入 react-router-dom
// 使用 ES6 的转译器,如 babel
import { BrowserRouter as Router, Route, Link } from 'react-router-dom';
// 不使用 ES6 的转译器
var BrowserRouter = require('react-router');
var Router = BrowserRouter.Router;
var Route = BrowserRouter.Route;
var Link = BrowserRouter.Link;
- BrowerRouter & HashRouter
使用Router
function RouterTest() {
return (
<Router>
<div>
<Link to="/">Home</Link>
<Link to="/about">About</Link>
<Link to="/topics">Topics</Link>
<hr />
<Route exact path="/" component={Home} />
<Route path="/about" component={About} />
<Route path="/topics" component={Topics} />
</div>
</Router>
);
}
// 然后 render <RouterTest />
-
Route 匹配 path 属性和当前 pathname,匹配就会 render component,不匹配 render null。如果 Route 不写 path 就可以匹配任何 pathname。
-
Switch 可以将 Route 归成一组,只 render 组内第一个匹配的元素。这样就可以把一个 404 放在组内最后一个。
-
NavLink 可以给匹配的路径设置 class,如下
<NavLink to="/foo" activeClassName="bar">Hello</NavLink>
- 还可以使用 <Redirect to="" /> 跳转
不使用JSX(旧版?)
const routes = {
path: '/',
component: App,
childRoutes: [
{ path: 'about', component: About },
{ path: 'inbox', component: Inbox },
]
}
React.render(<Router routes={routes} />, document.body)
获取URL,在组件传入参数 {match}
function Com({ match }) {
console.log(match)
}
如果是类定义组件?不会实时更新?
match: {
isExact: true,
params: {},
path: '/test/:id', // Route 组件的 path 属性,使用:开始
url: 'test/foo' // 匹配到的 URL
}
Route Rendering Props
<Route
path=""
render={props => <About {...props} extra={someVariable} />}
/>
Flux
Redux
npm install redux
Reducer
combineReducers()
Store
getSate()
dispatch(action)
subscribe(listener)
subscribe()
createStore()
React Redux
npm install react-redux
npm install --save-dev redux-devtools
创建 reducers
import { combineReducers } from 'redux'
import todos from './todos'
import visibilityFilter from './visibilityFilter'
const todoApp = combineReducers({
todos,
visibilityFilter
})
export default todoApp
使用 Provider 将 store 提供给 React 子组件
import React from 'react'
import { render } from 'react-dom'
import { Provider } from 'react-redux'
import { createStore } from 'redux'
import todoApp from './reducers/index'
import App from './components/App'
const store = createStore(todoApp, {})
render(
<Provider store={store}>
<App />
</Provider>,
document.getElementById('root')
)
使用 connect() 将 state 和 action 与 React 组件连接起来
useEffect
影响函数组件作用域之外的。
React首次渲染和之后的每次渲染都会调用一遍useEffect函数,而之前我们要用两个生命周期函数分别表示首次渲染(componentDidMonut)和更新导致的重新渲染(componentDidUpdate)。
useEffect中定义的函数的执行不会阻碍浏览器更新视图,也就是说这些函数时异步执行的,而componentDidMonut和componentDidUpdate中的代码都是同步执行的。个人认为这个有好处也有坏处吧,比如我们要根据页面的大小,然后绘制当前弹出窗口的大小,如果时异步的就不好操作了。
Tips
- useMemo 和 useCallback 到底怎么用?
- React 的性能优化(一)当 PureComponent 遇上 ImmutableJS
- 浅析ImmutableJS持久化数据结构的实现
- 一文读懂 React 组件渲染核心原理
- 从根上理解 React Hooks 的闭包陷阱
- 001-ant design pro 页面加载原理及过程,@connect 装饰器
- 从零实现一个React:Luster(一):JSX解析器
- setState异步、同步与进阶
相关文档
- React编写input组件传参共用onChange
- react学习笔记之react-router4.x中JS路由跳转
- 在 2017 年学习 React + Redux 的一些建议(上篇)
- react + ts 、react hooks学习笔记
- TS+React+Router+Mobx+Koa打造全栈应用
- ReactDOM.render为什么在componentDIdMount中执行返回的是null?
- 深入了解React组件重新渲染的条件和生命周期
- 利用shouldComponentUpdate钩子函数优化react性能以及引入immutable库的必要性
总结
React.CSSProperties
// mobx 追踪的是属性访问 而不是value
reactDOM.render 不一定是同步的
使用create react app部署生产目录?
修改 config 文件夹下面的 paths.js。
一个很好的React+Mobx的例子 https://www.jianshu.com/p/3d4e85f60141
Create React App v2 配置高级代理:
使用导航守卫(如用户权限判断):
事件
<button onClick={activateLasers}>
Activate Lasers
</button>
// 阻止默认行为
e.preventDefault();
向事件处理程序传递参数
在循环中,通常我们会为事件处理函数传递额外的参数。例如,若 id 是你要删除那一行的 ID,以下两种方式都可以向事件处理函数传递参数:
<button onClick={(e) => this.deleteRow(id, e)}>Delete Row</button>
<button onClick={this.deleteRow.bind(this, id)}>Delete Row</button>
上述两种方式是等价的,分别通过箭头函数和 Function.prototype.bind 来实现。
在这两种情况下,React 的事件对象 e 会被作为第二个参数传递。如果通过箭头函数的方式,事件对象必须显式的进行传递,而通过 bind 的方式,事件对象以及更多的参数将会被隐式的进行传递。
react 和 vue 区别
props是可以动态变化的,子组件也实时更新,在react中官方建议props要像纯函数那样,输入输出一致对应,而且不太建议通过props来更改视图;
Vue与React的区别
vue组件分为全局注册和局部注册,在react中都是通过import相应组件,然后模版中引用; props是可以动态变化的,子组件也实时更新,在react中官方建议props要像纯函数那样,输入输出一致对应,而且不太建议通过props来更改视图; 子组件一般要显示地调用props选项来声明它期待获得的数据。而在react中不必需,另两者都有props校验机制; 每个Vue实例都实现了事件接口,方便父子组件通信,小型项目中不需要引入状态管理机制,而react必需自己实现; 使用插槽分发内容,使得可以混合父组件的内容与子组件自己的模板; 多了指令系统,让模版可以实现更丰富的功能,而React只能使用JSX语法; Vue增加的语法糖computed和watch,而在React中需要自己写一套逻辑来实现; react的思路是all in js,通过js来生成html,所以设计了jsx,还有通过js来操作css,社区的styled-component、jss等;而 vue是把html,css,js组合到一起,用各自的处理方式,vue有单文件组件,可以把html、css、js写到一个文件中,html提供了模板引擎来处理。 react做的事情很少,很多都交给社区去做,vue很多东西都是内置的,写起来确实方便一些, 比如 redux的combineReducer就对应vuex的modules, 比如reselect就对应vuex的getter和vue组件的computed, vuex的mutation是直接改变的原始数据,而redux的reducer是返回一个全新的state,所以redux结合immutable来优化性能,vue不需要。 react是整体的思路的就是函数式,所以推崇纯组件,数据不可变,单向数据流,当然需要双向的地方也可以做到,比如结合redux-form,组件的横向拆分一般是通过高阶组件。而vue是数据可变的,双向绑定,声明式的写法,vue组件的横向拆分很多情况下用mixin。