阅读 63

【深入浅出 React 和 Redux】 笔记(上)

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 可以声明当前组件的接口规范:

  1. 这个组件支持哪些 prop
  2. 每个 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 :

  1. 通过 this.state 可以读取到组件的当前 state;

  2. 改变组件 state 必须要使用 this.setState 函数,而不能直接修改 this.state;

prop 和 state 对比

  1. prop 用于定义外部接口,state 用于记录内部状态;
  2. prop 的赋值在外部世界调用组件时候传入,state 的赋值在组件内部;
  3. 组件不因该改变 prop 的值,而state 存在的意义就是为了被改变,然后通过 render 函数把改变渲染到视图;

组件的生命周期

装载

  1. constructor
  2. getDefaultProps
  3. getInitialState
  4. componentWiillMount
  5. render
  6. componentDidMount

更新

  1. componentWillReceiveProps
  2. shouldComponentUpdate
  3. componentWillUpdate
  4. render
  5. componentDidUpdate

卸载

  1. 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 注意事项

  1. 创建时要读取 Store 的状态来初始化组件内部状态
  2. Store 变化时,组件内部状态要保持同步
  3. 组件只能派发 action 来改变Store 状态

Flux 的缺点

  1. Store 之间依赖关系
  2. 难以进行服务端渲染
  3. Store 混杂了逻辑和渲染

Redux (Flux的进化版)

graph LR
Action-->dispatch
dispatch-->Store
Store-->View
View-->Action

复制代码

在 Redux 框架下,一个 React组件基本上就是要完成两个功能:

  1. 和 Redux Store 打交道,读取 Store 的状态,用于初始化组件的状态,同时还要监听 Store 的状态改变;当 Store 状态改变时,需要更新组件状态,从而驱动组件重新渲染;当需要更新 State 状态时,就要派发 action 对象。
  2. 根据当前 props 和 state ,渲染出用户界面。

容器组件和傻瓜组件

  1. 容器组件: 承担所有和 Store 关联的工作,其 render 函数就是渲染傻瓜组件而已,只传递必要的 prop。
  2. 傻瓜组件: 纯函数,无状态组件,只根据容器组件传递的prop 渲染视图。

Context(上下文环境)

  1. 解决每个组件都要单独引入 store 带来的问题
  2. 解决多层嵌套组件 store 的传递问题,这样就不需要用 prop 层层传递了
  3. React 的 context 功能相当于创建了一个全局对象,所以这个功能要谨慎使用,但 Redux 的Store 因为封装的比较好,所以如果context 如果只用来传递 Store 的话,是个不错的选择。

React-Redux

  1. 不用自己再写 Provider, 封装到库里了
import { Provider } from 'react-redux'
复制代码
  1. connect: 连接容器组件和傻瓜组件
export default connect (mapStateToProps, mapDispatchToProps) (Counter)
复制代码