在Quora上,有人说:
首先,完全可以不用React编写应用程序
通量。
另外,我创建了这个可视化图表来快速展示两者的视图,可能是对那些不想阅读整个解释的人的快速回答:
但如果你仍然有兴趣了解更多,请继续阅读。
我相信你应该从纯React开始,然后学习Redux和Flux。
在你有一些React的实际经验之后,你会看到
Redux是否对你有帮助
也许你会觉得Redux完全适合你的应用,也可能适合你自己
会发现Redux在试图解决一个你没有的问题
真正的体验。
如果直接从Redux开始,可能会以过度设计告终
代码,更难维护的代码,甚至有更多的错误
回来的。
Redux文档:
Motivation As the requirements for JavaScript single-page applications have become increasingly complicated, our
code must manage more state than ever before. This state can include
server responses and cached data, as well as locally created data that
has not yet been persisted to the server. UI state is also increasing
in complexity, as we need to manage active routes, selected tabs,
spinners, pagination controls, and so on.
Managing this ever-changing state is hard. If a model can update
another model, then a view can update a model, which updates another
model, and this, in turn, might cause another view to update. At some
point, you no longer understand what happens in your app as you have
lost control over the when, why, and how of its state. When a system
is opaque and non-deterministic, it's hard to reproduce bugs or add
new features.
As if this wasn't bad enough, consider the new requirements becoming
common in front-end product development. As developers, we are
expected to handle optimistic updates, server-side rendering, fetching
data before performing route transitions, and so on. We find ourselves
trying to manage a complexity that we have never had to deal with
before, and we inevitably ask the question: Is it time to give up? The
answer is No.
This complexity is difficult to handle as we're mixing two concepts
that are very hard for the human mind to reason about: mutation and
asynchronicity. I call them Mentos and Coke. Both can be great when
separated, but together they create a mess. Libraries like React
attempt to solve this problem in the view layer by removing both
asynchrony and direct DOM manipulation. However, managing the state of
your data is left up to you. This is where Redux comes in.
Following in the footsteps of Flux, CQRS, and Event Sourcing, Redux
attempts to make state mutations predictable by imposing certain
restrictions on how and when updates can happen. These restrictions
are reflected in the three principles of Redux.
同样来自Redux文档:
Core Concepts Redux itself is very simple.
Imagine your app's state is described as a plain object. For example,
the state of a todo app might look like this:
{
todos: [{
text: 'Eat food',
completed: true
}, {
text: 'Exercise',
completed: false
}],
visibilityFilter: 'SHOW_COMPLETED'
}
This object is like a "model" except that there are no setters. This
is so that different parts of the code can’t change the state
arbitrarily, causing hard-to-reproduce bugs.
To change something in the state, you need to dispatch an action. An
action is a plain JavaScript object (notice how we don't introduce any
magic?) that describes what happened. Here are a few example actions:
{ type: 'ADD_TODO', text: 'Go to swimming pool' }
{ type: 'TOGGLE_TODO', index: 1 }
{ type: 'SET_VISIBILITY_FILTER', filter: 'SHOW_ALL' }
Enforcing that every change is described as an action lets us have a
clear understanding of what’s going on in the app. If something
changed, we know why it changed. Actions are like breadcrumbs of what
has happened. Finally, to tie state and actions together, we write a
function called a reducer. Again, nothing magic about it — it's just a
function that takes state and action as arguments, and returns the
next state of the app. It would be hard to write such a function for a
big app, so we write smaller functions managing parts of the state:
function visibilityFilter(state = 'SHOW_ALL', action) {
if (action.type === 'SET_VISIBILITY_FILTER') {
return action.filter;
} else {
return state;
}
}
function todos(state = [], action) {
switch (action.type) {
case 'ADD_TODO':
return state.concat([{ text: action.text, completed: false }]);
case 'TOGGLE_TODO':
return state.map((todo, index) =>
action.index === index ?
{ text: todo.text, completed: !todo.completed } :
todo
)
default:
return state;
}
}
And we write another reducer that manages the complete state of our
app by calling those two reducers for the corresponding state keys:
function todoApp(state = {}, action) {
return {
todos: todos(state.todos, action),
visibilityFilter: visibilityFilter(state.visibilityFilter, action)
};
}
This is basically the whole idea of Redux. Note that we haven't used
any Redux APIs. It comes with a few utilities to facilitate this
pattern, but the main idea is that you describe how your state is
updated over time in response to action objects, and 90% of the code
you write is just plain JavaScript, with no use of Redux itself, its
APIs, or any magic.