diff --git a/docs/basics/DataFlow.md b/docs/basics/DataFlow.md index 4524d4eac9..175f50e50a 100644 --- a/docs/basics/DataFlow.md +++ b/docs/basics/DataFlow.md @@ -11,7 +11,7 @@ Redux architecture revolves around a **strict unidirectional data flow**. This means that all data in an application follows the same lifecycle pattern, making the logic of your app more predictable and easier to understand. It also encourages data normalization, so that you don't end up with multiple, independent copies of the same data that are unaware of one another. -If you're still not convinced, read [Motivation](../introduction/Motivation.md) and [The Case for Flux](https://medium.com/@dan_abramov/the-case-for-flux-379b7d1982c6) for a compelling argument in favor of unidirectional data flow. Although [Redux is not exactly Flux](../introduction/PriorArt.md), it shares the same key benefits. +If you're still not convinced, read [Motivation](../understanding/thinking-in-redux/Motivation.md) and [The Case for Flux](https://medium.com/@dan_abramov/the-case-for-flux-379b7d1982c6) for a compelling argument in favor of unidirectional data flow. Although [Redux is not exactly Flux](../understanding/history-and-design/PriorArt.md), it shares the same key benefits. The data lifecycle in any Redux app follows these 4 steps: diff --git a/docs/basics/Store.md b/docs/basics/Store.md index 381aa25ab3..3cbbf0170a 100644 --- a/docs/basics/Store.md +++ b/docs/basics/Store.md @@ -68,7 +68,7 @@ You can see how this causes the state held by the store to change: -We specified the behavior of our app before we even started writing the UI. We won't do this in this tutorial, but at this point you can write tests for your reducers and action creators. You won't need to mock anything because they are just [pure](../introduction/ThreePrinciples.md#changes-are-made-with-pure-functions) functions. Call them, and make assertions on what they return. +We specified the behavior of our app before we even started writing the UI. We won't do this in this tutorial, but at this point you can write tests for your reducers and action creators. You won't need to mock anything because they are just [pure](../understanding/thinking-in-redux/ThreePrinciples.md#changes-are-made-with-pure-functions) functions. Call them, and make assertions on what they return. ## Source Code diff --git a/docs/faq/General.md b/docs/faq/General.md index 6ee398419b..e26ddf5af3 100644 --- a/docs/faq/General.md +++ b/docs/faq/General.md @@ -59,7 +59,7 @@ In the end, Redux is just a tool. It's a great tool, and there are some great re **Documentation** -- [Introduction: Motivation](../introduction/Motivation.md) +- [Thinking in Redux: Motivation](../understanding/thinking-in-redux/Motivation.md) **Articles** diff --git a/docs/introduction/README.md b/docs/introduction/README.md index 1ee1c3a050..6e0c9e62d5 100644 --- a/docs/introduction/README.md +++ b/docs/introduction/README.md @@ -1,9 +1,6 @@ # Introduction -- [Motivation](Motivation.md) - [Core Concepts](CoreConcepts.md) -- [Three Principles](ThreePrinciples.md) -- [Prior Art](PriorArt.md) - [Learning Resources](LearningResources.md) - [Ecosystem](Ecosystem.md) - [Examples](Examples.md) diff --git a/docs/recipes/ReducingBoilerplate.md b/docs/recipes/ReducingBoilerplate.md index cf5963afe0..4ec813343d 100644 --- a/docs/recipes/ReducingBoilerplate.md +++ b/docs/recipes/ReducingBoilerplate.md @@ -6,11 +6,11 @@ hide_title: true # Reducing Boilerplate -Redux is in part [inspired by Flux](../introduction/PriorArt.md), and the most common complaint about Flux is how it makes you write a lot of boilerplate. In this recipe, we will consider how Redux lets us choose how verbose we'd like our code to be, depending on personal style, team preferences, longer term maintainability, and so on. +Redux is in part [inspired by Flux](../understanding/history-and-design/PriorArt.md), and the most common complaint about Flux is how it makes you write a lot of boilerplate. In this recipe, we will consider how Redux lets us choose how verbose we'd like our code to be, depending on personal style, team preferences, longer term maintainability, and so on. ## Actions -Actions are plain objects describing what happened in the app, and serve as the sole way to describe an intention to mutate the data. It's important that **actions being objects you have to dispatch is not boilerplate, but one of the [fundamental design choices](../introduction/ThreePrinciples.md) of Redux**. +Actions are plain objects describing what happened in the app, and serve as the sole way to describe an intention to mutate the data. It's important that **actions being objects you have to dispatch is not boilerplate, but one of the [fundamental design choices](../understanding/thinking-in-redux/ThreePrinciples.md) of Redux**. There are frameworks claiming to be similar to Flux, but without a concept of action objects. In terms of being predictable, this is a step backwards from Flux or Redux. If there are no serializable plain object actions, it is impossible to record and replay user sessions, or to implement [hot reloading with time travel](https://www.youtube.com/watch?v=xsSnOQynTHs). If you'd rather modify data directly, you don't need Redux. diff --git a/docs/style-guide/style-guide.md b/docs/style-guide/style-guide.md index 390c516bef..b4e2f0da2f 100644 --- a/docs/style-guide/style-guide.md +++ b/docs/style-guide/style-guide.md @@ -430,7 +430,7 @@ If multiple dispatches are truly necessary, consider batching the updates in som ### Evaluate Where Each Piece of State Should Live -The ["Three Principles of Redux"](../introduction/ThreePrinciples.md) says that "the state of your whole application is stored in a single tree". This phrasing has been over-interpreted. It does not mean that literally _every_ value in the entire app _must_ be kept in the Redux store. Instead, **there should be a single place to find all values that _you_ consider to be global and app-wide**. Values that are "local" should generally be kept in the nearest UI component instead. +The ["Three Principles of Redux"](../understanding/thinking-in-redux/ThreePrinciples.md) says that "the state of your whole application is stored in a single tree". This phrasing has been over-interpreted. It does not mean that literally _every_ value in the entire app _must_ be kept in the Redux store. Instead, **there should be a single place to find all values that _you_ consider to be global and app-wide**. Values that are "local" should generally be kept in the nearest UI component instead. Because of this, it is up to you as a developer to decide what state should actually live in the Redux store, and what should stay in component state. **[Use these rules of thumb to help evaluate each piece of state and decide where it should live](../faq/OrganizingState.md#do-i-have-to-put-all-my-state-into-redux-should-i-ever-use-reacts-setstate)**. diff --git a/docs/introduction/PriorArt.md b/docs/understanding/history-and-design/PriorArt.md similarity index 97% rename from docs/introduction/PriorArt.md rename to docs/understanding/history-and-design/PriorArt.md index a5a2c2c2e0..c49299f45e 100644 --- a/docs/introduction/PriorArt.md +++ b/docs/understanding/history-and-design/PriorArt.md @@ -15,7 +15,7 @@ Redux was inspired by several important qualities of [Flux](https://facebook.git Unlike Flux, **Redux does not have the concept of a Dispatcher**. This is because it relies on pure functions instead of event emitters, and pure functions are easy to compose and don't need an additional entity managing them. Depending on how you view Flux, you may see this as either a deviation or an implementation detail. Flux has often been [described as `(state, action) => state`](https://speakerdeck.com/jmorrell/jsconf-uy-flux-those-who-forget-the-past-dot-dot-dot-1). In this sense, Redux is true to the Flux architecture, but makes it simpler thanks to pure functions. -Another important difference from Flux is that **Redux assumes you never mutate your data**. You can use plain objects and arrays for your state just fine, but mutating them inside the reducers is strongly discouraged. You should always return a new object, which is easy with the [object spread operator proposal](../recipes/UsingObjectSpreadOperator.md), or with a library like [Immutable](https://facebook.github.io/immutable-js). +Another important difference from Flux is that **Redux assumes you never mutate your data**. You can use plain objects and arrays for your state just fine, but mutating them inside the reducers is strongly discouraged. You should always return a new object, which is easy with the [object spread operator proposal](../../recipes/UsingObjectSpreadOperator.md), or with a library like [Immutable](https://facebook.github.io/immutable-js). While it is technically _possible_ to [write impure reducers](https://github.com/reduxjs/redux/issues/328#issuecomment-125035516) that mutate the data for performance corner cases, we actively discourage you from doing this. Development features like time travel, record/replay, or hot reloading will break. Moreover it doesn't seem like immutability poses performance problems in most real apps, because, as [Om](https://github.com/omcljs/om) demonstrates, even if you lose out on object allocation, you still win by avoiding expensive re-renders and re-calculations, as you know exactly what changed thanks to reducer purity. diff --git a/docs/introduction/Motivation.md b/docs/understanding/thinking-in-redux/Motivation.md similarity index 100% rename from docs/introduction/Motivation.md rename to docs/understanding/thinking-in-redux/Motivation.md diff --git a/docs/introduction/ThreePrinciples.md b/docs/understanding/thinking-in-redux/ThreePrinciples.md similarity index 90% rename from docs/introduction/ThreePrinciples.md rename to docs/understanding/thinking-in-redux/ThreePrinciples.md index cae5a4bfc5..008513c35b 100644 --- a/docs/introduction/ThreePrinciples.md +++ b/docs/understanding/thinking-in-redux/ThreePrinciples.md @@ -11,7 +11,7 @@ Redux can be described in three fundamental principles: ### Single source of truth -**The [global state](../Glossary.md#state) of your application is stored in an object tree within a single [store](../Glossary.md#store).** +**The [global state](../../Glossary.md#state) of your application is stored in an object tree within a single [store](../../Glossary.md#store).** This makes it easy to create universal apps, as the state from your server can be serialized and hydrated into the client with no extra coding effort. A single state tree also makes it easier to debug or inspect an application; it also enables you to persist your app's state in development, for a faster development cycle. Some functionality which has been traditionally difficult to implement - Undo/Redo, for example - can suddenly become trivial to implement, if all of your state is stored in a single tree. @@ -37,7 +37,7 @@ console.log(store.getState()) ### State is read-only -**The only way to change the state is to emit an [action](../Glossary.md#action), an object describing what happened.** +**The only way to change the state is to emit an [action](../../Glossary.md#action), an object describing what happened.** This ensures that neither the views nor the network callbacks will ever write directly to the state. Instead, they express an intent to transform the state. Because all changes are centralized and happen one by one in a strict order, there are no subtle race conditions to watch out for. As actions are just plain objects, they can be logged, serialized, stored, and later replayed for debugging or testing purposes. @@ -55,7 +55,7 @@ store.dispatch({ ### Changes are made with pure functions -**To specify how the state tree is transformed by actions, you write pure [reducers](../Glossary.md#reducer).** +**To specify how the state tree is transformed by actions, you write pure [reducers](../../Glossary.md#reducer).** Reducers are just pure functions that take the previous state and an action, and return the next state. Remember to return new state objects, instead of mutating the previous state. You can start with a single reducer, and as your app grows, split it off into smaller reducers that manage specific parts of the state tree. Because reducers are just functions, you can control the order in which they are called, pass additional data, or even make reusable reducers for common tasks such as pagination. diff --git a/website/_redirects b/website/_redirects index 52175f9b30..bdd7a5aa79 100644 --- a/website/_redirects +++ b/website/_redirects @@ -31,8 +31,8 @@ /introduction/coreconcepts* /introduction/core-concepts:splat /introduction/learningresources* /introduction/learning-resources:splat -/introduction/priorart* /introduction/prior-art:splat -/introduction/threeprinciples* /introduction/three-principles:splat +/introduction/priorart* /understanding/history-and-design/prior-art:splat +/introduction/threeprinciples* /understanding/thinking-in-redux/three-principles:splat /introduction /introduction/getting-started @@ -65,11 +65,11 @@ # Old old Gitbook links? /docs/introduction/CoreConcepts.html /introduction/core-concepts -/docs/introduction/Motivation.html /introduction/motivation +/docs/introduction/Motivation.html /understanding/thinking-in-redux/motivation /docs/introduction/Ecosystem.html* /introduction/ecosystem:splat /docs/introduction/CoreConcepts.html /introduction/core-concepts -/docs/introduction/PriorArt.html /introduction/prior-art -/docs/introduction/ThreePrinciples.html /introduction/three-principles +/docs/introduction/PriorArt.html /understanding/history-and-design/prior-art +/docs/introduction/ThreePrinciples.html /understanding/thinking-in-redux/three-principles /docs/introduction/Examples.html* /introduction/examples:splat /docs/introduction/ /introduction/getting-started @@ -144,4 +144,10 @@ /feedback /introduction/getting-started#help-and-discussion # PR preview for the new tutorial -/tutorials/quick-start/quick-start-part-1 /tutorials/essentials/part-1-overview-concepts \ No newline at end of file +/tutorials/quick-start/quick-start-part-1 /tutorials/essentials/part-1-overview-concepts + +# 2020 Site reorganization + +/introduction/motivation /understanding/thinking-in-redux/motivation +/introduction/three-principles /understanding/thinking-in-redux/three-principles +/introduction/prior-art /understanding/history-and-design/prior-art diff --git a/website/sidebars.js b/website/sidebars.js index 171dc4fb21..11a09bac5e 100755 --- a/website/sidebars.js +++ b/website/sidebars.js @@ -3,14 +3,26 @@ module.exports = { Introduction: [ 'introduction/getting-started', 'introduction/installation', - 'introduction/motivation', 'introduction/core-concepts', - 'introduction/three-principles', - 'introduction/prior-art', 'introduction/learning-resources', 'introduction/ecosystem', 'introduction/examples' ], + 'Understanding Redux': [ + { + type: 'category', + label: 'Thinking in Redux', + items: [ + 'understanding/thinking-in-redux/motivation', + 'understanding/thinking-in-redux/three-principles' + ] + }, + { + type: 'category', + label: 'History and Design', + items: ['understanding/history-and-design/prior-art'] + } + ], Tutorials: [ 'tutorials/tutorials-index', {