翻译<<You Might Not Need Redux>>

闲来无事, 翻译下我挺喜欢的一个程序员 Dan Abromov 的一篇文章《You Might Not Need Redux》, 因为我对于 redux 的用法也还很浅显, 里面也还存在着错误的用法, 多看看别人的一些优秀的工程, 慢慢会有更好的体会吧.

以下为翻译.

# 你也许并不需要 Redux

许多人经常在他们真的需要 Redux 之前就在项目中引入了它. "如果我的应用因为缺少了它而无法满足后续的扩展怎么办?", 但是在之后, 开发者又会对 Redux 给代码带来的迂回逻辑感到不满. "为什么我需要新建三个文件才能完成一个小小的功能?到底为什么?"

当人们遇到一些困难时会去抱怨 Redux, React, 函数式编程, 不可变数据和很多其他的事, 我也能理解他们. 把 Redux 和其它不需要"样板化"代码来更新应用状态的方式做比较然后得出 Redux 就是很繁琐的结论是很正常的事. 在某些方面来说确实如此, 设计的初衷就是这样.

Redux 提供了一些取舍. 它要求你:

不论你是否在使用 React 构建一个应用, 上面的那些限制条件都不是必要的. 进一步来说这些限制条件是非常严格的, 在你把他们使用到应用中的哪怕一部分的时候都应该考虑清楚.

你是否有足够充足的理由去这样做?

这些限制条件对我来说是非常有吸引力的, 因为它们能帮助建立一个有着如下特性的应用:

如果你正在开发一些可扩展的终端, JavaScript调试器或者其它的一些网页应用的话, 这是值得你去尝试一下的, 哪怕只是采用其中一部分的想法(顺带一说, 这些想法一直都存在)

然而, 如果你是刚开始学习 React 的初学者, 那么不要把 Redux 作为你的第一选择.

你要做的应该是按照 React 的思想去思考. 当你真的需要 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 install就能够使用 Redux. 哇哦!

你应该把这种做法使用到你的有状态的组件中吗? 大部分情况下不会的, 除非你计划能够从这种比较曲折的做法中获得收益. 在如今的开发中, 制定计划是很关键的事.

Redux 库本身只是一系列的工具, 能够帮助挂载 reducers 到一个单一的全局存储对象. 用多用少都随你意

但是如果你舍弃了某些东西, 请确保你能获取对应的回报.