This project was bootstrapped with Create React App for learn react.
In the project directory, you can run:
Runs the app in the development mode.
Open http://localhost:3000 to view it in the browser.
启动 jest 测试程序
将项目的隐藏配置文件打开,此过程不可逆
React 和 Vue 类似,主要从React React-router Redux 三个模块学习
- {} 写代码块
- <></> 写html
- class —> clssName
- style={{}} 里面是对象
- browserjs 将jsx解析为js
- React.createClass() React.Component 创建组件
- ReactDOM.render() 渲染到html页面
-
getInitialState 初始化组件state(es5 es6 写法)
-
componentWillMount 在组件加载完成前立即执行,还不能访问真实dom
-
componentDidMount 挂载后立即调用,DOM node初始化放这 异步请求统一放这
-
componentWillReceiveProps() 此事件的参数是指要更新的props
-
shouldComponentUpdate(object nextProps, object nextState) 控制react更新频率. 用来提升组件效率。
{ if(nextProps.content !== this.props.content) { return true } else { return false } } // 没有改变的时候不需要进行diff 比对
-
componentWillUpdate 在更新前被立即调用,不能在此调this.setState() react底层已经做完state对比
-
componentDidUpdate 在更新发生后立即调用。这是一个react组件更新完成后的通知
-
componentWillUnmount 在组件被卸载和摧毁前被立即调用。清理应该放这里
- react 父子组件通信都是单向数据流
- props 都是由父元素所传进来,不能更改,若要更改 props 则必须由父元素进行更改
- 当 React 发现 props 或是 state 更新时,就会重绘整个 UI
- 父组件往子组件传递数据:通过属性的方式,子组件通过this.props获取 (单向数据流 子组件不能更改传过来的值)
- 子组件往父组件传递数据:通过父组件向子组件传递事件,子组件触发事件回调给到父组件
正常流程
- state 数据
- JSX 模板
- 数据 + 模板 结合,生成真实的DOM,来显示(生成虚拟DOM — JS对象,用来描述真实DOM)
- state 发生改变
- 数据 + 模板 结合,生成真实的DOM, 替换原始的DOM
缺陷
- 第一次生成了一个完整的DOM片段
- 第二次生成一个完整DOM片段 (耗性能,浪费,diff优化)
优化
- 新的DOM 和 老DOM做比对,找差异
- 只更新有差异的DOM
整个过程
JSX —> React.createElement(‘div’, {}, ‘item’) —> 虚拟DOM —> 真实DOM
优点
- 性能提升
- 跨端可以实现 react-native\
- diff 比对发生在这个时候 同层比对 key 可以提升虚拟DOM比对 效率 删除 dom后 index 会变化 能不用index做key值就不用index
- 在 合成事件 和 生命周期钩子(除 componentDidUpdate) 中,setState是"异步”的 (判断是在事务流执行中,推入队列)
- 在 原生事件 和 setTimeout 中,setState是同步的,可以马上获取更新后的值。
将底层调度算法 由 同步递归 (不能暂停和恢复) 改为 单链表树遍历 可以通过任务分割,提升性能
- 页面路由
window.location.href = ‘www.baidu.com’ history.back()
- Hash Router
Window.location = ‘#hash’ Window.onhashchange = function() { console.log(‘current hash:’, window.location.hash) }
- H5 Router (既能操作hash 也能操作 路径 兼容比hash 差一点)
history.pushState('test','Title', '#name’) history.pushState('test','Title', '/name’) // 推进一个路由 window.onpopstate = function(e) {console.log('H5 ROUTER BACK', e.state)} // 后退时候执行 history.replaceState('test','Title', '/go’) // 替换当前路由
- this.props.match.params.id 获取路由参数
Redux = reducer + flux
- 只有store 才能改变store 不要在reducer里改变 store 返回 newStore
- Reducer 一定是个纯函数(给定固定的数,返回固定的值)
主要方法:
- createStore
- Store.dispatch
- Store.getState
- Store.subscribe // 订阅数据变更,注册监听器
- UI 组件
- 容器组件
- 无状态组件 只有render函数时候 不用extend 直接用函数来定义替代 (性能高)
- connect: 一个高阶组件,可以方便在 React 组件中使用 Redux;
(对dispatch 的升级)
- Redux-thunk 统一管理 异步请求 使actionCreator 返回 不仅可以是对象还可以是 函数
- Redux-logger
- Redux-saga 让action 不仅在reducer 接收 还可以在sagas.js 中接收
高阶组件不是组件,是 增强函数,可以输入一个元组件,返回出一个新的增强组件
应用场景
- 权限控制,通过抽象逻辑,统一对页面进行权限判断,按不同的条件进行页面渲染
- 性能监控,包裹组件的生命周期,进行统一埋点
- 代码复用,可以将重复的逻辑进行抽象
React 16.8 版本推出了一个新功能 (React Hooks),通过它,可以更好的在函数定义组件中使用 React 特性 使函数组件有类组件的功能
好处:
- 跨组件复用
- 类定义更为复杂
- 状态与UI隔离
重要钩子*
- 状态钩子 (useState):用于定义组件的 State,其到类定义中this.state的功能
- 生命周期钩子 (useEffect)