Redux 1 - 简介(Readme)
Redux is a predictable state container for JavaScript apps.
(If you’re looking for a WordPress framework, check out Redux Framework.)
Redux是一个可预测的JavaScript应用程序的状态容器。 (如果你要寻找的是同名WordPress框架,打开Redux Framework查看)。
It helps you write applications that behave consistently, run in different environments (client, server, and native), and are easy to test. On top of that, it provides a great developer experience, such as live code editing combined with a time traveling debugger.
基于Redux可以编写在不同运行环境中(客户端,服务端,和原生程序)行为一致的应用程序,并便于测试的进行。此外,其提供了优秀的开发体验,比如实时刷新和时间旅行调试。
You can use Redux together with React, or with any other view library.
It is tiny (2kB, including dependencies).
在包含依赖的情况下,Redux是一个只有2KB的微型库,可以和React或其他视图层库配合使用。
Learn Redux from its creator:
Getting Started with Redux (30 free videos)
跟着作者学Redux:
Redux入门 (30个免费视频)
赞誉(Testimonials)
“Love what you’re doing with Redux”
Jing Chen, creator of Flux
“因Redux而爱上工作”
Jing Chen,Flux作者
“I asked for comments on Redux in FB’s internal JS discussion group, and it was universally praised. Really awesome work.”
Bill Fisher, author of Flux documentation
“在FB内部的JS讨论组中讨论Redux时,大家普遍对其肯定”
Bill Fisher,Flux文档作者
“It’s cool that you are inventing a better Flux by not doing Flux at all.”
André Staltz, creator of Cycle
“非常漂亮,你发明了一个完全不同的更好的Flux”
André Staltz, Cycle作者
在进一步学习之前(Before Proceeding Further)
Also read why you might not be needing Redux:
“You Might Not Need Redux”
也读一下为什么有可能你并不需要Redux:
“你可能并不需要Redux”
开发缘由(Developer Experience)
I wrote Redux while working on my React Europe talk called “Hot Reloading with Time Travel”. My goal was to create a state management library with minimal API but completely predictable behavior, so it is possible to implement logging, hot reloading, time travel, universal apps, record and replay, without any buy-in from the developer.
Redux的开发源自我在React欧洲工作时对“Hot Reloading with Time Travel”问题的讨论。目标是创建一个最小API集合的状态管理库,并且可以完全预测程序执行的行为,实现日志记录,热加载,时间旅行,通用应用,记录和重演,同时避免对开发者造成额外的学习和工作成本。
影响(Influences)
Redux evolves the ideas of Flux, but avoids its complexity by taking cues from Elm.
Whether you have used them or not, Redux only takes a few minutes to get started with.
Redux是Flux思想的发展,同时避免了其复杂性,并吸取了Elm的解决思路。
无论是否使用过Redux,只需要几分钟即可以快速上手。
安装(Installation)
To install the stable version:
正式版本安装:
npm install --save redux
This assumes you are using npm as your package manager.
上面方法假设使用npm做包管理器。
If you’re not, you can access these files on unpkg, download them, or point your package manager to them.
如果不使用npm,可以从unpkg访问文件下载,或者使用熟悉的包管理器访问。
Most commonly people consume Redux as a collection of CommonJS modules. These modules are what you get when you import redux
in a Webpack, Browserify, or a Node environment. If you like to live on the edge and use Rollup, we support that as well.
通常情况下将Redux作为一组CommonJS模块的集合,可以在Webpack,Browserify或Node环境中将其引入。同时也对新式的Rollup提供支持。
If you don’t use a module bundler, it’s also fine. The redux
npm package includes precompiled production and development UMD builds in the dist
folder. They can be used directly without a bundler and are thus compatible with many popular JavaScript module loaders and environments. For example, you can drop a UMD build as a <script>
tag on the page, or tell Bower to install it. The UMD builds make Redux available as a window.Redux
global variable.
可以在不使用模块管理器的情况下直接引用redux
。在npm
包的dist
folder目录中包含预编译生产和开发环境的UMD构建版本。可以将其直接引用,同时更好的与大多数主流的JavaScritp模块加载器兼容。比如,在页面中直接使用<script>
tag引用,也可以使用Bower安装。UMD版本会创建一个window.Redux
的全局变量。
The Redux source code is written in ES2015 but we precompile both CommonJS and UMD builds to ES5 so they work in any modern browser. You don’t need to use Babel or a module bundler to get started with Redux.
Redux源码使用ES2015的语法,但已经预编译好了ES5语法的CommonJS和UMD版本可以运行在任何现代浏览器中。不需要引用Babel或打包器就可以直接开始Redux学习。
配套包(Complementary Packages)
Most likely, you’ll also need the React bindings and the developer tools.
npm install --save react-redux
npm install --save-dev redux-devtools
Note that unlike Redux itself, many packages in the Redux ecosystem don’t provide UMD builds, so we recommend using CommonJS module bundlers like Webpack and Browserify for the most comfortable development experience.
需要提醒的是,Redux生态中的大多数库并不提供UMD构建版本,建议使用Webpack和Browserify等CommonJS类的模块打包器以获得更好的开发体验。
核心原则(The Gist)
The whole state of your app is stored in an object tree inside a single store.
The only way to change the state tree is to emit an action, an object describing what happened.
To specify how the actions transform the state tree, you write pure reducers.
应用的整个状态树必须被存储在一个单例对象store中。
更新状态树的唯一方法是派发一个action对象来描述发生的情况。
特别需要指出的是,用来处理状态树更新的reducers函数必须是纯函数。
That’s it!
这就是Redux的核心原则!
import { createStore } from 'redux'
/**
* This is a reducer, a pure function with (state, action) => state signature.
* It describes how an action transforms the state into the next state.
*
* The shape of the state is up to you: it can be a primitive, an array, an object,
* or even an Immutable.js data structure. The only important part is that you should
* not mutate the state object, but return a new object if the state changes.
*
* In this example, we use a `switch` statement and strings, but you can use a helper that
* follows a different convention (such as function maps) if it makes sense for your
* project.
*/
function counter(state = 0, action) {
switch (action.type) {
case 'INCREMENT':
return state + 1
case 'DECREMENT':
return state - 1
default:
return state
}
}
// Create a Redux store holding the state of your app.
// Its API is { subscribe, dispatch, getState }.
let store = createStore(counter)
// You can use subscribe() to update the UI in response to state changes.
// Normally you'd use a view binding library (e.g. React Redux) rather than subscribe() directly.
// However it can also be handy to persist the current state in the localStorage.
store.subscribe(() =>
console.log(store.getState())
)
// The only way to mutate the internal state is to dispatch an action.
// The actions can be serialized, logged or stored and later replayed.
store.dispatch({ type: 'INCREMENT' })
// 1
store.dispatch({ type: 'INCREMENT' })
// 2
store.dispatch({ type: 'DECREMENT' })
// 1
Instead of mutating the state directly, you specify the mutations you want to happen with plain objects called actions. Then you write a special function called a reducer to decide how every action transforms the entire application’s state.
在Redux中禁止直接修改状态,需要用一个简单的actions对象来描述修改。最后在reducer方法中如何处理整个程序的状态。
If you’re coming from Flux, there is a single important difference you need to understand. Redux doesn’t have a Dispatcher or support many stores. Instead, there is just a single store with a single root reducing function. As your app grows, instead of adding stores, you split the root reducer into smaller reducers independently operating on the different parts of the state tree. This is exactly like how there is just one root component in a React app, but it is composed out of many small components.
如果了解Flux,需要理解Redex和Flux的一个重要区别。Redux没有Dispatcher,也不支持多个store。在Redux中,只包含根reduce方法中处理的一个store对象单例。当你的应用复杂化的同时,不需要增加新的store对象,只需要将根reducer拆分为更小的reducer来独立处理状态树的不同部分。类似于React应用中只有一个根组件,但是其由更多的小组件组成。
This architecture might seem like an overkill for a counter app, but the beauty of this pattern is how well it scales to large and complex apps. It also enables very powerful developer tools, because it is possible to trace every mutation to the action that caused it. You can record user sessions and reproduce them just by replaying every action.
在计数器应用中使用这种结构模式显得过于复杂,但当应用扩展到更大、更复杂的应用时将发现其优势。可以配合强大的开发者工具,以用来追踪action触发的每一次修改。可以记录用户会话,并通过重播每一个action重现操作场景。
跟着作者学Redux(Learn Redux from Its Creator)
Getting Started with Redux is a video course consisting of 30 videos narrated by Dan Abramov, author of Redux. It is designed to complement the “Basics” part of the docs while bringing additional insights about immutability, testing, Redux best practices, and using Redux with React. This course is free and will always be.
Redux入门是由Redux作者Dan Abramov创建的30集视频教程。该教程包含完整的文档“基础”部分和不可变数据、测试、Redux最佳实践和在React中如何使用Redux。该系列课程将永远免费。
“Great course on egghead.io by @dan_abramov - instead of just showing you how to use #redux, it also shows how and why redux was built!”
Sandrino Di Mattia
“Plowing through @dan_abramov ‘Getting Started with Redux’ - its amazing how much simpler concepts get with video.”
Chris Dhanaraj
“This video series on Redux by @dan_abramov on @eggheadio is spectacular!”
Eddie Zaneski
“This series of videos on Redux by @dan_abramov is repeatedly blowing my mind - gunna do some serious refactoring”
Laurence Roberts
So, what are you waiting for?
开始学习吧!
Watch the 30 Free Videos!
免费观看学习30个视频!
If you enjoyed my course, consider supporting Egghead by buying a subscription. Subscribers have access to the source code for the example in every one of my videos, as well as to tons of advanced lessons on other topics, including JavaScript in depth, React, Angular, and more. Many Egghead instructors are also open source library authors, so buying a subscription is a nice way to thank them for the work that they’ve done.
如果喜欢我的课程,可以考虑付费订阅Egghead来支持我。订阅者可以访问每一个视频中的示例源码,同时可以获得大量的其他主题的高级课程,包括深入JavaScript,React,Angular等等。很多Egghead讲师同时也是开源代码库的作者,付费订阅是对他们工作付出的一种良好方法。
文档(Documentation)
- 简介(Introduction)
- 基础(Basics)
- 高级(Advanced)
- 技巧(Recipes)
- 常见问题(Troubleshooting)
- 术语(Glossary)
- API参考(API Reference)
For PDF, ePub, and MOBI exports for offline reading, and instructions on how to create them, please see: paulkogel/redux-offline-docs.
如果要导出PDF,ePub或MOBIle以离线阅读,可以从paulkogel/redux-offline-docs学习如何创建。
实例(Examples)
- Counter Vanilla (source)
- Counter (source)
- Todos (source)
- Todos with Undo (source)
- TodoMVC (source)
- Shopping Cart (source)
- Tree View (source)
- Async (source)
- Universal (source)
- Real World (source)
If you’re new to the NPM ecosystem and have troubles getting a project up and running, or aren’t sure where to paste the gist above, check out simplest-redux-example that uses Redux together with React and Browserify.
对于NPM新手,启动项目会比较困难,或者不确定上面的要点要写在什么位置,签出入门Redux示例基于React和Browserify开始Redux学习。
讨论(Discussion)
Join the #redux channel of the Reactiflux Discord community.
加入Reactiflux Discord社区的#redux频道。
感谢(Thanks)
- The Elm Architecture for a great intro to modeling state updates with reducers;
- Turning the database inside-out for blowing my mind;
- Developing ClojureScript with Figwheel for convincing me that re-evaluation should “just work”;
- Webpack for Hot Module Replacement;
- Flummox for teaching me to approach Flux without boilerplate or singletons;
- disto for a proof of concept of hot reloadable Stores;
- NuclearJS for proving this architecture can be performant;
- Om for popularizing the idea of a single state atom;
- Cycle for showing how often a function is the best tool;
- React for the pragmatic innovation.
Special thanks to Jamie Paton for handing over the redux
NPM package name.
特别感谢Jamie Paton将redux
NPM包名转让。
Logo
You can find the official logo on GitHub.
可以在GitHub上找到官方Logo。
升级日志(Change Log)
This project adheres to Semantic Versioning.
Every release, along with the migration instructions, is documented on the Github Releases page.
项目遵循语义话版本。
每次发版以及相应的变更说明,在Github在发布页面都可以找到对应文档。
赞助商(Patrons)
The work on Redux was funded by the community.
Meet some of the outstanding companies that made it possible:
Redux工作由社区赞助。
没有下面这些优秀的公司,就没有Redux:
See the full list of Redux patrons.
许可(License)
MIT