深入学习react和redux 之 redux 总结

Redux的基本原则

1. 唯一数据源
2. 保持状态只读
3. 数据改变只能通过纯函数完成

容器组件和木偶组件

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

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

我们将一个任务拆分成两个组件,然后两个组件嵌套起来,完成原本一个组件完成的所有任务

  • 与 Redux Store打交道的组件,处于外层,所以被叫做 容器组件
  • 对于只专心负责渲染界面的组件,处于内层,叫做展示组件或称为木偶组件

React和Redux应用规范和要点

模块化应用要点

  • 代码文件的组织结构
  • 确定模块的边界
  • store的状态树

代码文件的组织方式

按角色组织

MVC中,应用代码分为 Controller Model View ,分别代表 种模块角色,就是把所有的 Con oller 代码放在 controllers 目录下,把所有的 Model 代码放在 models录下,把View 代码放在 views 目录下 这种组织代码的方式,叫做“按角色组织”

按功能组织

把完成同一应用功能的代码放在一个目录下,一个应用功能包含多个角色的代码。在Redux中,不同的角色就是reducer、actions和视图,而应用功能对应的就是用户界面上的交互模块。

todoList/
    actons.js
    actionTypes.jS
    index.js
    reducer.js
    views/
        cornponent.js
        container.js
filter/
    actions.js
    actionTypes.js
    index. js
    reducer.js
    views/
        cornponent.js
        container.js 
  • actionTypes.js 定义action类型;
  • actions.js 定义action构造函数,决定了这个功能模块可以接受的动作;
  • reducer.js 定义了这个功能模块如何相应actions.js 中定义的动作;
  • views目录,包含这个功能模块中所以React组件
  • index.js 文件的统一入口

模块接口

我下面我们以功能模块todoList和filter,为例。
当我们在filter模块想要使用todoList的action构造函数和视图该如何导入呢?
bad

import * as actions from '../todoList/actions';
import container as TodoList from './todoList/views/container';

因为filter模块依赖todoList模块的内部结构。
Good
在 todoList/index.js中,代码如下:

import * as actions from './action.js'
import reducer from './reducer.js'
import view from './views/container.js'

export {actions,reducer,view}

//下面在filter模块导入todoList的代码
import {actions,reducer,view as TodoList} from '../todoList';

状态树的设计

  • 一个模块控制一个状态节点
  • 避免冗余数据
  • 树形结构扁平

一个模块控制一个状态节点
Store上的每个state只能通过reducer来更改,而每个reducer只能更改redux状态树上一个节点下的数据。

React组件在React-redux中性能优化

react 在渲染数据时采用的"浅层比较"的方式只看这两个prop是不是同一个对象的引用。

样式写法优化

Bad

<Todo style={
  {color:'red'}}/>

Good

//确保初始化只执行一次,不要放到render中
const fooStyle={color:'red'};

<Foo style={fooStyle}/>

props 函数传递方式

Bad

<TodoItem
    key={item.id}
    text={item.text}
    completed={item.completed}
    onToggle={()=>{ onToggleTodo(item.id)}}
    onRemove={()=>onRemoveTodo(item.id)}
 />

上面的做法中,我们将回调函数传递给子组件的onClick事件,redux认为每次都是一个新的函数,所以,我们可以将要传递的参数以属性传递给组件,让子组件去传递函数(mapDispathToProps中)

<TodoItem
    key={item.id}
    id={item.id}
    text={item.text}
    completed={item.completed}
 />
 
const mapDispatchToProps = (dispath: any, ownProps: any) => {
    const { id } = ownProps;
    return {
        onToggle: () => { console.log('onToggle'); dispath(toggleTodo(id)) },
        onRemove: () => dispath(removeTodo(id))
    }
}
//木偶组件应该用connect包起来,让redux 判读props是否改变
export default connect(null,mapDispatchToProps)(TodoItem);

React组件访问服务器的优缺点

优点:

  • 直接简单,容易理解
  • 代码非常清晰

缺点:

  • 状态放到组件,使其变得庞大复杂

改进:
我们可以使用 Redux做状态管理来

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值