Повышение производительности react и redux с reselect

Storage Engines

  • localStorage
  • sessionStorage
  • AsyncStorage react-native
  • localForage recommended for web
  • electron storage Electron support via electron store
  • redux-persist-filesystem-storage react-native, to mitigate storage size limitations in android (#199, #284)
  • redux-persist-node-storage for use in nodejs environments.
  • redux-persist-sensitive-storage react-native, for sensitive information (uses react-native-sensitive-info).
  • redux-persist-expo-filesystem react-native, similar to redux-persist-filesystem-storage but does not require linking or ejecting CRNA/Expo app. Only available if using Expo SDK (Expo, create-react-native-app, standalone).
  • redux-persist-expo-securestore react-native, for sensitive information using Expo’s SecureStore. Only available if using Expo SDK (Expo, create-react-native-app, standalone).
  • redux-persist-fs-storage react-native-fs engine
  • redux-persist-cookie-storage Cookie storage engine, works in browser and Node.js, for universal / isomorphic apps
  • redux-persist-weapp-storage Storage engine for wechat mini program, also compatible with wepy
  • redux-persist-webextension-storage Storage engine for browser (Chrome, Firefox) web extension storage
  • @bankify/redux-persist-realm Storage engine for Realm database, you will need to install Realm first
  • redux-persist-pouchdb Storage engine for PouchDB.
  • custom any conforming storage api implementing the following methods: . (NB: These methods must support promises)

#Immutable Data

Data Structures

Immutable persistent data collections for Javascript


Frozen immutable arrays/objects, backwards-compatible with JS


Immutable JS objects with a natural API


Utilities for treating frozen JS objects as persistent immutable collections.


Immutable Update Utilities

Immutable updates with normal mutative code, using Proxies


A drop-in replacement for react-addons-update


Simpler alternative to immutability-helpers and Immutable.js


Immutable version of the dot-prop lib, with some extensions


Immutable/Redux Interop

combineReducers equivalent that works with Immutable.js Maps


combineReducers equivalent that works with seamless-immutable values


Learn Redux

We have a variety of resources available to help you learn Redux, no matter what your background or learning style is.

If you’re brand new to Redux and want to understand the basic concepts, see:

  • The behind building Redux, the , and the .
  • The
  • Redux creator Dan Abramov’s on Egghead.io
  • Redux co-maintainer Mark Erikson’s and
  • If you learn best by looking at code and playing with it, check out our list of , available as separate projects in the Redux repo, and also as interactive online examples on CodeSandbox.
  • The section of the . Here’s a top list of our recommended tutorials:

Once you’ve picked up the basics of working with actions, reducers, and the store, you may have questions about topics like working with asynchronous logic and AJAX requests, connecting a UI framework like React to your Redux store, and setting up an application to use Redux:

  • The covers working with async logic, middleware, routing.
  • The Redux docs page points to recommended articles on a variety of Redux-related topics.
  • Sophie DeBenedetto’s 8-part series shows how to put together a basic CRUD app from scratch.

Going from a TodoMVC app to a real production application can be a big jump, but we’ve got plenty of resources to help:

  • Redux creator Dan Abramov’s builds on his first video series and covers topics like middleware, routing, and persistence.
  • The answers many common questions about how to use Redux, and the has information on handling derived data, testing, structuring reducer logic, and reducing boilerplate.
  • Redux co-maintainer Mark Erikson’s demonstrates real-world intermediate and advanced techniques for working with React and Redux (also available as ).
  • Our community has created thousands of Redux-related libraries, addons, and tools. The lists our recommendations, and there’s a complete listing available in the .
  • If you’re looking to learn from actual application codebases, the addons catalog also has a list of .

The of the is our official resource for all questions related to learning and using Redux. Reactiflux is a great place to hang out, ask questions, and learn — come join us!


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 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. If you’d rather modify data directly, you don’t need Redux.

Actions look like this:


It is a common convention that actions have a constant type that helps reducers (or Stores in Flux) identify them. We recommend that you use strings and not Symbols for action types, because strings are serializable, and by using Symbols you make recording and replaying harder than it needs to be.

In Flux, it is traditionally thought that you would define every action type as a string constant:


Why is this beneficial? It is often claimed that constants are unnecessary, and for small projects, this might be correct. For larger projects, there are some benefits to defining action types as constants:

  • It helps keep the naming consistent because all action types are gathered in a single place.
  • Sometimes you want to see all existing actions before working on a new feature. It may be that the action you need was already added by somebody on the team, but you didn’t know.
  • The list of action types that were added, removed, and changed in a Pull Request helps everyone on the team keep track of scope and implementation of new features.
  • If you make a typo when importing an action constant, you will get . Redux will immediately throw when dispatching such an action, and you’ll find the mistake sooner.

It is up to you to choose the conventions for your project. You may start by using inline strings, and later transition to constants, and maybe later group them into a single file. Redux does not have any opinion here, so use your best judgment.


Reducer Combination

An expanded version of , which allows passing as a third argument to all slice reducers.

A variation that allows defining cross-slice dependencies for ordering and data passing


Reducer Composition

Provides sequential composition of reducers at the same level


A collection of composable reducer transformers


Reducer factory functions for common data structures: counters, maps, lists (queues, stacks), sets


Higher-Order Reducers

Effortless undo/redo and action history for your reducers

Ignore redux actions by array or filter function

Reset the redux state on certain actions

A reducer enhancer to enable type-agnostic optimistic updates

Использование Redux

Разберём устройство Redux и механизм его работы.

Неизменяемое дерево состояний

В Redux общее состояние приложения представлено одним объектом JavaScript — state (состояние) или state tree (дерево состояний). Неизменяемое дерево состояний доступно только для чтения, изменить ничего напрямую нельзя. Изменения возможны только при отправке action (действия).


Действие (action) — это JavaScript-объект, который лаконично описывает суть изменения:

Единственное требование к объекту действия — это наличие свойства , значением которого обычно является строка.

Типы действий должны быть константами

В простом приложении тип действия задаётся строкой. По мере разрастания функциональности приложения лучше переходить на константы:

и выносить действия в отдельные файлы. А затем их импортировать:

Генераторы действий

Генераторы действий (actions creators) — это функции, создающие действия.

Обычно инициируются вместе с функцией отправки действия:

Или при определении этой функции:


При запуске действия обязательно что-то происходит и состояние приложения изменяется. Это работа редукторов.

Что такое редуктор

Редуктор (reducer) — это чистая функция, которая вычисляет следующее состояние дерева на основании его предыдущего состояния и применяемого действия.

Чистая функция работает независимо от состояния программы и выдаёт выходное значение, принимая входное и не меняя ничего в нём и в остальной программе. Получается, что редуктор возвращает совершенно новый объект дерева состояний, которым заменяется предыдущий.

Чего не должен делать редуктор

Редуктор — это всегда чистая функция, поэтому он не должен:

  • мутировать аргументы;
  • мутировать состояние. Вместо этого создаётся новое состояние с помощью ;
  • иметь побочные эффекты (никаких API-вызовов с какими-либо изменениями);
  • вызывать нечистые функции. Это функции, результат которых зависит от чего-то кроме их аргументов (например, или ).

Поскольку состояние в сложных приложениях может сильно разрастаться, к каждому действию применяется не один, а сразу несколько редукторов.

Subscribirse a los cambios de estado

Podemos suscribirnos al store para enterarnos cuando cambia y poder modificar nuestra aplicación en consecuencia usando store.subscribe(callback).

import store from './store.js';// nos suscribimos al store, esto nos devuelve// una función que nos sirve para desuscribirnosconst unsubscribe = store.subscribe(() => {    // vemos el nuevo store    console.log(store.getState());    // nos desuscribimos    unsubscribe();});


Como se puede ver Redux es bastante simple de empezar a usar, y gracias a que es tan simple es posible combinarlo con prácticamente cualquier framework o librería que exista, ya sea React, Backbone, Angular 1/, Ember, etc.

#Higher-Level Abstractions

An abstraction over Redux, Redux-Saga and Reselect. Provides a framework for your app’s actions, reducers, selectors and sagas. It empowers Redux, making it as simple to use as setState. It reduces boilerplate and redundancy, while retaining composability.

A simplified layer over Redux. No action creators or explicit dispatching, with a built-in simple side effects system.

Takes a defined structure and uses ‘behaviors’ to create a set of actions, reducer responses and selectors.

Provides minimal abstraction on top of Redux, to allow easy composability, easy async requests, and sane testability.


Networks and Sockets

Fetches data with Axios and dispatches start/success/fail actions


Reads API call actions, fetches, and dispatches FSAs


An opinionated connector between socket.io and redux.


Integration between Firebase, React, and Redux

Async Behavior

Buffers all actions into a queue until a breaker condition is met, at which point the queue is released

FSA-compliant middleware for Redux to debounce actions.

Queue actions when offline and dispatch them when getting back online.


Integrates with any analytics services, can track while offline, and decouples analytics logic from app logic

Analytics and tracking with an easy API for writing your own adapters

Watches for Flux Standard Actions with meta analytics values and processes them

Уроки курса

  • 1

    Познакомиться с курсом и подготовить окружение.


  • 2

    Познакомиться с Redux, научиться диспатчить Actions.




  • 3

    Изучить способы разбиения контейнера на части.




  • 4


  • 5

    Научиться подключать и использовать мидлвары.


  • 6

    Научиться подключать Redux к React.




  • 7


  • 8


  • 9


  • 10


  • 11

    Познакомиться с концепцией селекторов. Научиться писать эффективные выборки из Redux.




  • 12


  • 13

    Асинхронные действия

    Научиться правильно работать с асинхронными запросами и их представлением в виде конечных автоматов.



#Splitting Reducers

Here is our code so far. It is rather verbose:


Is there a way to make it easier to comprehend? It seems like and are updated completely independently. Sometimes state fields depend on one another and more consideration is required, but in our case we can easily split updating into a separate function:


Note that also accepts —but is an array! Now gives just a slice of the state to manage, and knows how to update just that slice. This is called reducer composition, and it’s the fundamental pattern of building Redux apps.

Let’s explore reducer composition more. Can we also extract a reducer managing just ? We can.

Below our imports, let’s use ES6 Object Destructuring to declare :




Now we can rewrite the main reducer as a function that calls the reducers managing parts of the state, and combines them into a single object. It also doesn’t need to know the complete initial state any more. It’s enough that the child reducers return their initial state when given at first.


Note that each of these reducers is managing its own part of the global state. The parameter is different for every reducer, and corresponds to the part of the state it manages.

This is already looking good! When the app is larger, we can split the reducers into separate files and keep them completely independent and managing different data domains.

Finally, Redux provides a utility called that does the same boilerplate logic that the above currently does. With its help, we can rewrite like this:


Note that this is equivalent to:


You could also give them different keys, or call functions differently. These two ways to write a combined reducer are equivalent:


All does is generate a function that calls your reducers with the slices of state selected according to their keys, and combines their results into a single object again. And like other reducers, does not create a new object if all of the reducers provided to it do not change state.

Connecting Firebase realtime database with Redux store

This step might look like the hard part but it is actually very easy. First let’s install dependencies and we break down how Firebase database works.

Now we need to initialize Firebase in our application. Create new directory and inside create new file . Here we import firebase SDK initialize the app create database reference and export it. We’ll use the database reference for to create new taks or complete them later on in module. You might ask what is object. We’ll create it later on when I show you how to create your own Firebase application.

Before we move to module let’s have a word about how Firebase real-time database works. In our case we will store list of tasks in the database. We call them “todos”. We will attach listener on this list of tasks and each time the list changes, our application will know there was a change in the data. It will fetch the new data from Firebase database and then displays it. What this means is that we don’t have to tell our application to fetch data again when we create new task or complete one. Our application will know that.

Now let’s create module. Inside directory create new folder . And here create files and . Types file just store string constants for action types. Index is entry point for our actions module and will contain exactly 3 actions. is gonna add new task to the list of taks, is gonna remove it. And will listen for changes and if there are some it will fetch the data. Then it will call method. This method takes one argument which is object with and . Type represents action type so the reducer know if it should handle the action. And represents actual data.

Now it is time to glue all these things together using React component. But first let’s create your own Firebase application first


Redux reduces the boilerplate of Flux stores considerably by describing the update logic as a function. A function is simpler than an object, and much simpler than a class.

Consider this Flux store:


With Redux, the same update logic can be described as a reducing function:


The statement is not the real boilerplate. The real boilerplate of Flux is conceptual: the need to emit an update, the need to register the Store with a Dispatcher, the need for the Store to be an object (and the complications that arise when you want a universal app).

It’s unfortunate that many still choose Flux framework based on whether it uses statements in the documentation. If you don’t like , you can solve this with a single function, as we show below.

Generating Reducers

Let’s write a function that lets us express reducers as an object mapping from action types to handlers. For example, if we want our reducers to be defined like this:


We can write the following helper to accomplish this:


This wasn’t difficult, was it? Redux doesn’t provide such a helper function by default because there are many ways to write it. Maybe you want it to automatically convert plain JS objects to Immutable objects to hydrate the server state. Maybe you want to merge the returned state with the current state. There may be different approaches to a “catch all” handler. All of this depends on the conventions you choose for your team on a specific project.

The Redux reducer API is , but how you create those reducers is up to you.

#Handling Actions

Now that we’ve decided what our state object looks like, we’re ready to write a reducer for it. The reducer is a pure function that takes the previous state and an action, and returns the next state.


It’s called a reducer because it’s the type of function you would pass to . It’s very important that the reducer stays pure. Things you should never do inside a reducer:

  • Mutate its arguments;
  • Perform side effects like API calls and routing transitions;
  • Call non-pure functions, e.g. or .

We’ll explore how to perform side effects in the advanced walkthrough. For now, just remember that the reducer must be pure. Given the same arguments, it should calculate the next state and return it. No surprises. No side effects. No API calls. No mutations. Just a calculation.

With this out of the way, let’s start writing our reducer by gradually teaching it to understand the actions we defined earlier.

We’ll start by specifying the initial state. Redux will call our reducer with an state for the first time. This is our chance to return the initial state of our app:


One neat trick is to use the ES6 default arguments syntax to write this in a more compact way:


Now let’s handle . All it needs to do is to change on the state. Easy:


Note that:

  1. We don’t mutate the . We create a copy with . is also wrong: it will mutate the first argument. You must supply an empty object as the first parameter. You can also enable the object spread operator proposal to write instead.

  2. We return the previous in the case. It’s important to return the previous for any unknown action.

#Side Effects

Widely Used

Dispatch functions, which are called and given and as parameters. This acts as a loophole for AJAX calls and other async behavior.

Best for: getting started, simple async and complex synchronous logic.


Handle async logic using synchronous-looking generator functions. Sagas return descriptions of effects, which are executed by the saga middleware, and act like «background threads» for JS applications.

Best for: complex async logic, decoupled workflows


Handle async logic using RxJS observable chains called «epics».
Compose and cancel async actions to create side effects and more.

Best for: complex async logic, decoupled workflows


A port of the Elm Architecture to Redux that allows you to sequence your effects naturally and purely by returning them from your reducers. Reducers now return both a state value and a side effect description.

Best for: trying to be as much like Elm as possible in Redux+JS


Side effects lib built with observables, but allows use of callbacks, promises, async/await, or observables. Provides declarative processing of actions.

Best for: very decoupled async logic



Dispatch promises as action payloads, and have FSA-compliant actions dispatched as the promise resolves or rejects.


Sensible, declarative, convention-based promise handling that guides users in a good direction without exposing the full power of dispatch.



Change Subscriptions

Watch for state changes based on key paths or selectors


Centralized subscriptions to state changes based on paths



Store enhancer that can debounce subscription notifications


Store enhancer that allows dispatching arrays of actions


Store enhancer that accepts batched actions


Higher-order reducer that handles batched actions



Persist and rehydrate a Redux store, with many extensible options


Persistence layer for Redux with flexible backends


Persistent store for Offline-First apps, with support for optimistic UIs


Population, Random Events & Pedestrian Ai

  • 100% re-configured population levels, with options to customize to your liking.
  • Brand new pedestrian spawning, adding story-line characters into the natural population.
  • More and varying police now spawn on the streets and hunt down criminals! Watch out!
  • Fluctuating population levels between different times of day and location.
  • Brand new vehicle spawning, and the addition of all dlc vehicles into the sopawn cycles.
  • Now see up to 8 police cars with helicopters chasing down ai criminals in the city!
  • Random events and crime happen much more frequently.
  • Highly increased scenario pedestrians to add more life to the city! (drinking, eating, walking dogs, jogging, hiking, general activity, etc).
  • All pedestrians react much different, with much larger variation. Depending on the individual you approach, reactions will different.
  • Ai handles car crashes, popped tires, violence, destruction and death, while behind the wheel, different. Enjoy the Shocking reactons!
  • Trains now travel much faster!


Mientras que las acciones describen que algo ocurrió no especifican como nuestra aplicación reacciona a ese algo. De esto se encargan los Reducers.

Ya que el estado de nuestra aplicación es un único objeto es buena idea empezar a pensar cual va a ser la forma más básica antes de empezar a programar, como ejemplo vamos a suponer que hacemos una aplicación de TODOs por lo que nuestro store va a tener el siguiente formato:

{    todos: [],}

Ahora que definimos la forma de nuestro store podemos empezar a crear reducers. Un reducer es una función pura que recibe el estado actual y una acción y devuelve el nuevo estado.

(prevState, action) => nextState

Se llaman reducers porque son el tipo de funciones que pasarías a Array.prototype.reduce(reducer). Es muy importante que se mantengan como funciones puras. Algunas cosas que nunca deberías hacer en un reducer:

  • Modificar sus argumentos directamente (lo correcto es crear una copia)
  • Realizar acciones con efectos secundarios como llamadas a una API o cambiar rutas
  • Ejecutar funciones no puras como Date.now() o Math.random()

Que se mantengan puros quiere decir que pasandole los mismos parámetros debería siempre devolver el mismo resultado. Ahora vamos a programar un reducer para nuestra acción ADD_TODO:

// cargamos el método de Redux para// poder combinar reducersimport { combineReducers } from 'redux';function todos(state = [], action) {  switch(action.type) {  case 'ADD_TODO':    // creamos una copia del state actual    const copy = Array.from(state);    // modificamos lo que necesitamos    copy.push(action.payload.text)    // retornamos el nuevo state    return copy;  default:    // si el action.type no existe o no concuerda    // con ningunos de los casos definidos    // devolvemos el estado sin modificar    return state;  }}// combinamos nuestros reducers// los keys que usemos para nuestros reducers// van a ser usados como keys en nuestro store// en este ejemplo sería: { todos: [], }const reducers = combineReducers({    todos,});export default reducers;

Como se ve arriba Redux nos provee una función llamada combineReducers() que recibe un objeto con los reducers que definimos y los combina.

El nombre que le pongamos a cada reducer es usado como propiedad del store que creemos y es donde se va a guardar el estado devuelto por el reducer.

Weapons, Melee, Explosions & Damage

  • Brand new weapon recoil for realistic weapon feedback.
  • New rate of fire for all weapons, close to real life counter part.
  • Much farther weapon distance, with realistic bullet speeds, and drop distance. (hardly noticeable but just right)
  • New reload times, animations, and proper ammo/clip sizes.
  • Much farther lock on distance, bullets are now a projectile instead of instant hit.
  • All rockets travel much farther, and will not detonate unless they make contact within 800 meters.
  • Brand new weapon smoke, muzzle flash, and barrel trail effects, for both the player and ai.
  • All aerial vehicles with rockets, fire them at a near semi-auto rate.
  • New blast radius for explosions, including damage limits, shock wave distance and power.
  • Melee fighting has been improved to allow enemies to counter more, take more damage, throw faster punches and dodge.
  • All playable characters are now 70% MORE likely to punch, rather than kick.
  • Peds and enemies can now take more bullets! Shots from behind are no longer instant kill (unless head-shots).
  • Some materials can now be shot through (thin wood, thin metal, plants, drywall, plastics etc.

Example Usage

Because is so flexible, it may help to see some additional examples of how it can be called:

Inject just dispatch and don’t listen to store

Inject all action creators (addTodo, completeTodo, …) without subscribing to the store

Inject dispatch and every field in the global state

Inject dispatch and todos

Inject todos and all action creators

Inject todos and all action creators (addTodo, completeTodo, …) as actions

Inject todos and a specific action creator (addTodo)

Inject todos and specific action creators (addTodo and deleteTodo) with shorthand syntax

Inject todos, todoActionCreators as todoActions, and counterActionCreators as counterActions

Inject todos, and todoActionCreators and counterActionCreators together as actions

Inject todos, and all todoActionCreators and counterActionCreators directly as props

Inject todos of a specific user depending on props

Inject todos of a specific user depending on props, and inject props.userId into the action


Сергей Позднышев

Асинхронные действия

Ну вот и все, прогресс профессии 100%. Даже немного грустно.
Спасибо за интересный курс.

Николай Макаров

React Redux

Хочу сказать огромное спасибо за это задание, меня посетило ощущение, что теперь я знаю еще больше. На прошлое упражнение у меня ушло порядка 8-ми часов, а это я сделал меньше, чем за час, ниразу не запинаясь, и практически полностью похоже на решение учителя.

Спасибо ребят, вы лучшие! 🙂

Dale Barbara

React Redux

Хорошее задание ) Спасибо, что не даете забыть функциональный подход к реализации )

Дмитрий Петров

React Redux

Обдумывал целый день решение! В итоге решил! Оказалось коробка Redux действительно магическая! И я понял что овладел этой магией, функциональное программирование- это чудо, которым я наконец то начал пропитываться!

Irina Nikolaidi


Все мои предыдущие попытки освоить Ридакс были безуспешны. Благодаря Хекслету, кажется, получится переломить эту тенденцию.

В этом задании основной сложностью для меня было понять, как работает функция createStore. Неясно было, когда нужно передавать initState, а когда нет, и как createStore его будет обрабатывать.

Искала дополнительные источники. Документация не давала ответа на этот вопрос. Наткнулась на статью «Изучаем ридакс и пишем свой мини-ридакс». Там была ссылка на упрощенную реализацию ридакса: https://next.plnkr.co/edit/OX7hNMlFXtEA2d7aSU1Y?p=preview&preview

Мне она помогла. Думаю, для кого-нибудь тоже окажется полезной.


Usage Examples:

  1. Hot Module Replacement
  2. Code Splitting

Basic Usage

Basic usage involves adding and to your setup. IMPORTANT Every app needs to decide how many levels of state they want to «merge». The default is 1 level. Please read through the for more information.

// configureStore.js

import { createStore } from 'redux'
import { persistStore, persistReducer } from 'redux-persist'
import storage from 'redux-persist/lib/storage' // defaults to localStorage for web

import rootReducer from './reducers'

const persistConfig = {
  key 'root',

const persistedReducer = persistReducer(persistConfig, rootReducer)

export default () => {
  let store = createStore(persistedReducer)
  let persistor = persistStore(store)
  return { store, persistor }

If you are using react, wrap your root component with PersistGate. This delays the rendering of your app’s UI until your persisted state has been retrieved and saved to redux. NOTE the loading prop can be null, or any react instance, e.g.

import { PersistGate } from 'redux-persist/integration/react'

// ... normal setup, create store and persistor, import components etc.

const App = () => {
  return (
    Provider store={store}>
      PersistGate loading={null} persistor={persistor}>
        RootComponent >

Before Proceeding Further

Redux is a valuable tool for organizing your state, but you should also consider whether it’s appropriate for your situation. Don’t use Redux just because someone said you should — take some time to understand the potential benefits and tradeoffs of using it.

Here are some suggestions on when it makes sense to use Redux:

  • You have reasonable amounts of data changing over time
  • You need a single source of truth for your state
  • You find that keeping all your state in a top-level component is no longer sufficient

Yes, these guidelines are subjective and vague, but this is for good reason. The point at which you should integrate Redux into your application is different for every user and different for every application.

Ссылка на основную публикацию