1th章 配置环境
creat-react-app
Facebook 官方的脚手架工具,使我们不必过早的关注技术栈细节,通过一个已经完成配置的应用,快速开始 React 应用的开发
npm install --global creat-react-app
安装完成后,在 命令行中 creat-react-app -V 查看版本号,如果有版本号则正常;
初始化一个应用:
create-react-app <project-name> cd <project-name> npm start //启动命令
eject 命令
执行此命令会把封装好的项目结构打乱,把所有配置暴露给开发者,要慎用
2th章 设计高质量的react组件
组件的数据
prop (property的简写), 定义:对外接口;
prop的类型不是字符串类型时,在 JSX 中必须用 {} 把prop 值包住,外层 {}是react 语法,内部{}代表一个对象常量;
render()函数只能返回一个元素,所以要渲染多个组件时,外层需要加包裹元素,如 div;
子组件内,需要通过 super(props) 调用父类 React.Component 的构造函数,不然无法通过 this.props 访问父组件传递的 props 值;
propTypes 可以声明当前组件的接口规范:
- 这个组件支持哪些 prop
- 每个 prop 因该是什么样的格式
propTypes 检查只是一个辅助开发的功能,并不会改变组件的行为,所以只需要在开发过程中定义以避免错误,发布代码时候用自动化工具将其去掉(babel-react-optimize)
Counter.propTypes = { caption: PropTypes.string.isRequired, initValue: PropTypes.number }
defaultProps 用来定义prop默认值
Counter.defaultProps = { initValue: 0 }
state
定义:组件内部数据
react 组件不能修改传入的 prop,所以需要 state 记录自身数据变化
state 的初始化
在组件的构造函数尾部,通过对 this.state 的赋值完成对组件state的初始化,代码如下:
constructor(props) { ... this.state = { count: props.initValue } }
读取和更新 state :
- 通过 this.state 可以读取到组件的当前 state;
- 改变组件 state 必须要使用 this.setState 函数,而不能直接修改 this.state;
prop 和 state 对比
- prop 用于定义外部接口,state 用于记录内部状态;
- prop 的赋值在外部世界调用组件时候传入,state 的赋值在组件内部;
- 组件不因该改变 prop 的值,而state 存在的意义就是为了被改变,然后通过 render 函数把改变渲染到视图;
组件的生命周期
装载
- constructor
- getDefaultProps
- getInitialState
- componentWiillMount
- render
- componentDidMount
更新
- componentWillReceiveProps
- shouldComponentUpdate
- componentWillUpdate
- render
- componentDidUpdate
卸载
- componentWillUnmount // 卸载只涉及一个函数
向父组件传递数据
利用 prop 传递函数来解决,组件的 prop 可以是任何 JavaScript 对象。
React 组件中 state 和 prop 的局限
数据冗余和重复、数据一致性
3th章 从 Flux 到 Redux
Flux 和 Redux 的特点:单向数据流
Flux
Flux 的特点: 更严格的数据流控制,Flux 架构下,应用的状态被放在了 Store 中,React 组件只是扮演了 View 的作用,被动根据Store 的状态来渲染。
Flux 的结构:
graph LR Action-->Dispatcher Dispatcher-->Store Store-->View View-->Dispatcher
Redux 与 Flux 一脉相承,是 Flux 的进化版本
store 并不一定非要存储一些东西,也可以只提供获取数据的方法,store 提供的数据安全可以另一个 store 计算而来
在 react 中使用 Flux 注意事项
- 创建时要读取 Store 的状态来初始化组件内部状态
- Store 变化时,组件内部状态要保持同步
- 组件只能派发 action 来改变Store 状态
Flux 的缺点
- Store 之间依赖关系
- 难以进行服务端渲染
- Store 混杂了逻辑和渲染
Redux (Flux的进化版)
graph LR Action-->dispatch dispatch-->Store Store-->View View-->Action
在 Redux 框架下,一个 React组件基本上就是要完成两个功能:
- 和 Redux Store 打交道,读取 Store 的状态,用于初始化组件的状态,同时还要监听 Store 的状态改变;当 Store 状态改变时,需要更新组件状态,从而驱动组件重新渲染;当需要更新 State 状态时,就要派发 action 对象。
- 根据当前 props 和 state ,渲染出用户界面。
容器组件和傻瓜组件
- 容器组件: 承担所有和 Store 关联的工作,其 render 函数就是渲染傻瓜组件而已,只传递必要的 prop。
- 傻瓜组件: 纯函数,无状态组件,只根据容器组件传递的prop 渲染视图。
Context(上下文环境)
- 解决每个组件都要单独引入 store 带来的问题
- 解决多层嵌套组件 store 的传递问题,这样就不需要用 prop 层层传递了
- React 的 context 功能相当于创建了一个全局对象,所以这个功能要谨慎使用,但 Redux 的Store 因为封装的比较好,所以如果context 如果只用来传递 Store 的话,是个不错的选择。
React-Redux
- 不用自己再写 Provider, 封装到库里了
import { Provider } from 'react-redux'
- connect: 连接容器组件和傻瓜组件
export default connect (mapStateToProps, mapDispatchToProps) (Counter)