05月22, 2017

【译】你真的需要Redux吗?

原文:https://medium.com/@dan_abramov/you-might-not-need-redux

开发人员通常还没搞清楚是否需要Redux就选择了Redux。 “如果我们的应用程序不上Redux,以后不能扩展怎么办?” 等引入Redux后,开发人员就开始郁闷了。 “为什么一个简单的功能都至少需要写三个文件?” 为什么呢?

开发人员对Redux、React、函数式编程、不变性(immutability)等诸多技术多有怨言,我非常理解他们,因为以前并不需要这么复杂的代码来更新状态,和传统的方式相比很容易得出结论,Redux太复杂了。是的,Redux就是这样设计的。

Redux提供了一种权衡,对开发要求如下:

  • 将应用程序状态描述为纯对象和数组。
  • 将系统状态变化描述为普通对象。
  • 将业务逻辑变化描述为纯函数。

无论是否使用React,这些约束对于构建应用程序都不是必须的。实际上这些都是强约束,即使你只打算在应用程序的某些部分采纳这种模式,也需要认真考量。

现在你还有很好的理由这样做吗?

这些约束对我充满吸引力,因为在此基础上构建应用具有以下优势:

  • 将状态持久化到本地,然后下次启动的时候直接加载这些状态。
  • 服务器端预置状态,并发送给HTML客户端,客户端直接根据状态启动。
  • 将用户操作序列化,并打包到状态快照里面,自动产生缺陷报告,开发人员通过重放用户操作快速重现错误。
  • 通过在网络传递操作对象即可实现协作,而且不需要对代码进行大改。
  • 不需要对代码进行大手术就可以维护操作撤销(undo)历史记录。
  • 开发历史状态可回溯,当代码发生变化时,很容易通过回放操作历史计算出当前状态。
  • 给开发工具提供了全面的检查和控制的能力,开发人员因此可以自己构建所需要的工具。
  • 当UI变化的时候,大量的业务逻辑还可以继续重用。

如果您正在开发一个可扩展终端,JavaScript调试器或其他类型的web应用,Redux也许值得一试,或者至少考虑采纳其中一些思路(其实这并不是什么新东西)

但是,如果您只是学习React,就没有必要让Redux成为您的首选。

先学会用React的方式来思考。

如果你真的需要它,或者如果你想尝试新事物,再选择Redux。但是就像你对待其他的具有高约束性的工具的一样, 一定要慎重考虑后再选择。

如果你觉得用Redux太难受了,可能是因为你或者你的团队过于照本宣科了,Redux只是你工具箱中的一种工具,实践出真知。

最后要记住,即使不用Redux,也可以借鉴Redux的思路。例如,一个使用本地状态的React组件:

import React, { Component } from 'react';

class Counter extends Component {
  state = { value: 0 };

  increment = () => {
    this.setState(prevState => ({
      value: prevState.value + 1
    }));
  };

  decrement = () => {
    this.setState(prevState => ({
      value: prevState.value - 1
    }));
  };

  render() {
    return (
      <div>
        {this.state.value}
        <button onClick={this.increment}>+</button>
        <button onClick={this.decrement}>-</button>
      </div>
    )
  }
}

这个示例非常典型,非常好,是可以复用的模式。

使用本地状态完全没问题。

Redux实际上提供了一种权衡:通过增加中间环节来对“发生了什么”和“该如何变化”进行解耦。

这样一定对吗?一定好吗?不,这只是一个权衡。

例如,我们可以从已有的组件中提取出reducer:

import React, { Component } from 'react';

const counter = (state = { value: 0 }, action) => {
  switch (action.type) {
    case 'INCREMENT':
      return { value: state.value + 1 };
    case 'DECREMENT':
      return { value: state.value - 1 };
    default:
      return state;
  }
}

class Counter extends Component {
  state = counter(undefined, {});

  dispatch(action) {
    this.setState(prevState => counter(prevState, action));
  }

  increment = () => {
    this.dispatch({ type: 'INCREMENT' });
  };

  decrement = () => {
    this.dispatch({ type: 'DECREMENT' });
  };

  render() {
    return (
      <div>
        {this.state.value}
        <button onClick={this.increment}>+</button>
        <button onClick={this.decrement}>-</button>
      </div>
    )
  }
}

注意:我们没有运行npm安装就能使用Redux。酷不酷。

你是否应该把这种方式引入到状态组件中?也许不。除非你能从这种额外的中间环节受益,先好好规划,记住兵马未动,粮草先行。

Redux库其实就是将reducer挂到一个全局的状态对象(store) 的一套助手方法集,你完全可以根据需要选择如何使用Redux,丰俭由人。

最后记得,付出要有收获。

本文链接:http://www.xiaojichao.com/post/you-might-not-need-redux.html

-- EOF --

Comments