redux thunk что это

Зачем нужен redux-thunk?

Сегодня с коллегой возникла небольшая дискуссия, я утверждал, что redux-thunk очень удобная надстройка (middleware) над redux и позволяет создавать асинхронные экшены.
Коллега возразил, зачем нужен redux-thunk, когда можно сделать вот так:

Т.е он импортит store в определенный файл проекта и вызывает несколько экшенов

По началу я впал в ступор, действительно, зачем redux-thunk, если можно испортить стор, но позже проанализировав ситуацию, пришел к выводу, что асинхронные экшены, например как в примере выше загрузка профиля должна иметь 3 состояния:
— старт загрузки профиля (для отображения лоадера)
— данные профиля успешно загружены
— возникла ошибка при загрузке данных
исходя из этого, если действовать по методу коллеги, необходимо создавать для каждого действия отдельную функцию (экшены)

Вот пример с использованием redux-thunk

Преимущества redux-thunk очевидны, и больше всего мне нравится то, что с помощью redux-thunk всю логику можно хранить в экшенах и тем самым разгрузить компоненты, это одновременно делает проект чище, ведь логика будет находится внутри экшенов, вместо того, чтобы импортить стор в разные части проекта

Что вы скажите, какое мнение верно, и имеет ли права на жизнь предложенное коллегой решение?

redux thunk что это. Смотреть фото redux thunk что это. Смотреть картинку redux thunk что это. Картинка про redux thunk что это. Фото redux thunk что это

Если я правильно понял вашего коллегу, то речь была не о том, что нужно асинхронные функции через setTimeout вызывать, а это был просто пример, как сделать какой-то кусочек «типа асинхронным».
Его довод был в том, что вместо вызова dispatch из замыкания (полученного с помощью redux-thunk, например) он вызывал store.dispatch напрямую (то есть у объекта store, и этот store импортировал бы в каждом файле).

В остальном, все очень четко расписано в ответе Дэна Абрамова, который привел holymotion.
Если быть кратким, то вам нужна функция dispatch, ведь именно через нее вы «диспатчите» свои экшены. Вы не можете в асинхронном ответе написать:

Поэтому вы были бы обязаны в каждый action creator, который является асинхронным, передавать бы помимо нужных вам аргументов, еще и функцию dispatch из своего контейнера. Что не удобно. (это все есть по ссылке на stackoverflow, но более подробно)

Источник

Зачем нужен redux-thunk. Где его использовать, а где можно обойтись и без него

Йо-йо. Так как я сейчас работаю frontend-разработчиком и пишу свой код на react’е мне приходится работать и с redux, чтобы хранить данные и как-то их изменять. Конечно же изменение этих данных влечёт новый рендер.

Из-за того, что данных бывает очень много и, порой, нужно сделать множество преобразований за одно действие, причём изменить данные или запросить их на сервере простого redux не хватает. Приходится пользоваться middleware redux-thunk. В этой статье я хочу поделиться своим опытом использования redux-thunk, рассказать где без него не обойтись, а где для лучшего UX его миновать.

Что такое middleware

Это какая-то функция, которая берёт текущий store, текущий action и что-то делает с этим. Более подробно лучше прочитать в документации.

Redux-thunk — это как раз такая функция, которая, что-то делает со store.

Зачем использовать redux-thunk

Если вы задались этим вопросом, значит вы уже пользуетесь redux и знаете, что обычно action является простым объектом, который используется в reduser, a action creator имеет примерно такой вид:

В данном примере данные будут переданы в переменной array, эти данные и получит reduser и передаст в store.

Пример 1

В примере выше всё очень просто, но часто мы ещё не имеем ни каких данных и их нужно запросить с сервера. Тут то нам и нужен middleware для того, чтобы вызвать dispatch в то время, когда данные уже будут получены. Тогда наш action creator примет такой вид:

В этой функции мы явно вызываем dispatсh, в тот момент, когда мы получим данные.

Пример 2

Кроме того, что мы не имеем данных, бывает, что нужно вызвать сразу несколько action’ов. Например вы хотите сделать ваш компонент неактивным, пока идёт запрос. Вы можете сделать несколько вызовов dispatch в одном экшене.

В данном примере в начале я вызываю другой action creator (setDetouchStadia), делаю запрос на сервер и в любом случает вызываю его заново.

Пример 3

Иногда за одно действие может быть вызвано огромное количество изменений. Сейчас (декабрь 2019) я работаю над плеером для музыки 8bit. Как у любого плеера у него есть пульт для управления треками и список треков, которые можно выбрать. В момент выбора трека мне нужно сделать множество действий, и знать кое-какие данные из store.

Как я уже говорил redux-thunk, как и другие middleware даёт нам доступ к store:

Переменная getState — это функция, которая возвращает текущий экземпляр store.

Алгоритм действий, которые я решил, чтобы выполнялся при выборе трека:

В итоге у меня получился вот такой action creator

Когда не нужно использовать redux-thunk

Как может показаться, каждый раз, когда мы используем запросы к серверу мы должны использовать его… А вот и нет.

Хороший пример у меня был совсем недавно в статье про getDerivedStateFromProps. Там говорилось об отмене подписке на уведомления. Там использовался хук реакта и state компонента для изменения состояния подписки и ожидание нового значения из store. Но можно пойти другим путём.

По сути нам нужно было изменить в redux данные об элемент, но если бы мы отправили запрос на сервер в action и ждали ответ сервера то казалось бы, что наш сайт тормозит. Следовательно нам нужно изменить данные и отослать запрос на сервер. И так

Как вы видите здесь не подразумевалось получение важных данных с сревера. По-этому лучше тут не использовать middleware если оно не нужно. Вполне возможно, что у вас есть только подобные случаи в приложении и не нужно увеличивать бандл без необходимости.

Ещё пример

Иногда нам нужно изменить данные опираясь на state и не нужно получать весь, store целиком. В этом случае тоже можно отказаться от thunk а за место него использовать функции в самом reduser’е. Как я показал выше.

Про react и redux стало на статью больше. Если вы не согласны с моим мнение то можете написать своё в комментариях. А если согласны то не постесняйтесь поддержать проект денежкой)

Поддержи Xakplant

Я давно хочу развить видеоверсию, но пока этого не получается из-за нехватки ресурсов. Сейчас я собираю деньги на новый компьютер и микрофон. Поддержи xaklant и ты увидишь полезные видео быстрее.

Источник

Writing Logic with Thunks

Thunk Overview​

What is a «thunk»?​

The word «thunk» is a programming term that means «a piece of code that does some delayed work». Rather than execute some logic now, we can write a function body or code that can be used to perform the work later.

For Redux specifically, «thunks» are a pattern of writing functions with logic inside that can interact with a Redux store’s dispatch and getState methods.

Using thunks requires the redux-thunk middleware to be added to the Redux store as part of its configuration.

Thunks are the standard approach for writing async logic in Redux apps, and are commonly used for data fetching. However, they can be used for a variety of tasks, and can contain both synchronous and asynchronous logic.

Writing Thunks​

A thunk function is a function that accepts two arguments: the Redux store dispatch method, and the Redux store getState method. Thunk functions are not directly called by application code. Instead, they are passed to store.dispatch() :

A thunk function may contain any arbitrary logic, sync or async, and can call dispatch or getState at any time.

In the same way that Redux code normally uses action creators to generate action objects for dispatching instead of writing action objects by hand, we normally use thunk action creators to generate the thunk functions that are dispatched. A thunk action creator is a function that may have some arguments, and returns a new thunk function. The thunk typically closes over any arguments passed to the action creator, so they can be used in the logic:

In either case, the thunk is dispatched by calling the action creator, in the same way as you’d dispatch any other Redux action:

Why Use Thunks?​

Thunks allow us to write additional Redux-related logic separate from a UI layer. This logic can include side effects, such as async requests or generating random values, as well as logic that requires dispatching multiple actions or access to the Redux store state.

Redux reducers must not contain side effects, but real applications require logic that has side effects. Some of that may live inside components, but some may need to live outside the UI layer. Thunks (and other Redux middleware) give us a place to put those side effects.

It’s common to have logic directly in components, such as making an async request in a click handler or a useEffect hook and then processing the results. However, it’s often necessary to move as much of that logic as possible outside the UI layer. This may be done to improve testability of the logic, to keep the UI layer as thin and «presentational» as possible, or to improve code reuse and sharing.

In a sense, a thunk is a loophole where you can write any code that needs to interact with the Redux store, ahead of time, without needing to know which Redux store will be used. This keeps the logic from being bound to any specific Redux store instance and keeps it reusable.

Detailed Explanation: Thunks, Connect, and «Container Components»

Thunk Use Cases​

Because thunks are a general-purpose tool that can contain arbitrary logic, they can be used for a wide variety of purposes. The most common use cases are:

Thunks are «one-shot» functions, with no sense of a lifecycle. They also cannot see other dispatched actions. So, they should not generally be used for initializing persistent connections like websockets, and you can’t use them to respond to other actions.

Thunks are best used for complex synchronous logic, and simple to moderate async logic such as making a standard AJAX request and dispatching actions based on the request results.

Redux Thunk Middleware​

Dispatching thunk functions requires that the redux-thunk middleware has been added to the Redux store as part of its configuration.

Adding the Middleware​

If you need to add the thunk middleware to a store manually, that can be done by passing the thunk middleware to applyMiddleware() as part of the setup process.

How Does the Middleware Work?​

To start, let’s review how Redux middleware work in general.

With that in mind, we can look at the specifics of the thunk middleware.

Injecting Config Values Into Thunks​

The thunk middleware does have one customization option. You can create a custom instance of the thunk middleware at setup time, and inject an «extra argument» into the middleware. The middleware will then inject that extra value as the third argument of every thunk function. This is most commonly used for injecting an API service layer into thunk functions, so that they don’t have hardcoded dependencies on the API methods:

There can only be one extra argument value. If you need to pass in multiple values, pass in an object containing those.

The thunk function will then receive that extra value as its third argument:

Thunk Usage Patterns​

Dispatching Actions​

Thunks have access to the dispatch method. This can be used to dispatch actions, or even other thunks. This can be useful for dispatching multiple actions in a row (although this is a pattern that should be minimized), or orchestrating complex logic that needs to dispatch at multiple points in the process.

Accessing State​

It’s preferable to put as much logic as possible in reducers, but it’s fine for thunks to also have additional logic inside as well.

Since the state is synchronously updated as soon as the reducers process an action, you can call getState after a dispatch to get the updated state.

One other reason to consider accessing state in a thunk is to fill out an action with additional info. Sometimes a slice reducer really needs to read a value that isn’t in its own slice of state. A possible workaround to that is to dispatch a thunk, extract the needed values from state, and then dispatch a plain action containing the additional info.

Async Logic and Side Effects​

When making async requests, it’s standard to dispatch actions before and after a request to help track loading state. Typically, a «pending» action before the request and a loading state enum is marked as «in progress». If the request succeeds, a «fulfilled» action is dispatched with the result data, or a «rejected» action is dispatched containing the error info.

This pattern is admittedly awkward to write and read. In most cases you can probably get away with a more typical try/catch pattern where the request and the dispatch(requestSucceeded()) are back-to-back. It’s still worth knowing that this can be an issue.

Returning Values from Thunks​

The thunk middleware does this, by returning whatever the called thunk function returns.

The most common use case for this is returning a promise from a thunk. This allows the code that dispatched the thunk to wait on the promise to know that the thunk’s async work is complete. This is often used by components to coordinate additional work:

This is not a recommended practice per se, but it’s semantically legal and will work fine.

Using createAsyncThunk ​

Writing async logic with thunks can be somewhat tedious. Each thunk typically requires defining three different action types + matching action creators for «pending/fulfilled/rejected», plus the actual thunk action creator + thunk function. There’s also the edge cases with error handling to deal with.

Since this is an abstraction for the specific use case of async requests, createAsyncThunk does not address all possible use cases for thunks. If you need to write synchronous logic or other custom behavior, you should still write a «normal» thunk by hand yourself instead.

Fetching Data with RTK Query​

Redux Toolkit has a new RTK Query data fetching API. RTK Query is a purpose built data fetching and caching solution for Redux apps, and can eliminate the need to write any thunks or reducers to manage data fetching.

RTK Query actually uses createAsyncThunk internally for all requests, along with a custom middleware to manage cache data lifetimes.

First, create an «API slice» with definitions for the server endpoints your app will talk to. Each endpoint will auto-generate a React hook with a name based on the endpoint and request type, like useGetPokemonByNameQuery :

Then, add the generated API slice reducer and custom middleware to the store:

Finally, import the auto-generated React hook into your component and call it. The hook will automatically fetch data when the component mounts, and if multiple components use the same hook with the same arguments, they will share the cached results:

We encourage you to try out RTK Query and see if it can help simplify the data fetching code in your own apps.

Источник

Redux и Thunk вместе с React. Руководство для чайников.

redux thunk что это. Смотреть фото redux thunk что это. Смотреть картинку redux thunk что это. Картинка про redux thunk что это. Фото redux thunk что это

Если вы также как и я читали документацию к Redux, смотрели видео от Dan’а, прошли курс от Wes’а и до сих пор не совсем понимаете как использовать Redux, то я надеюсь что эта статья поможет вам.

После нескольких попыток использования Redux я начал что-то понимать и подумал, что лучше записать процесс преобразования уже существующего приложения в приложение использующее Redux и Redux Thunk. Если вы не знаете что такое Thunk, не беспокойтесь, мы будем использовать его для отправки асинхронных запросов с Redux.

Это руководство предполагает, что у вас есть базовые знания React и ES6/2015.

Способ без Redux

Создание основы

Не так уж и много, но это хорошее начало.

Делаем его динамичным

Жёстко закодированные элементы не сделают ничего хорошего для нашего компонента, поэтому давайте получим наш массив items через JSON API, который также позволит нам устанавливать isLoading и hasErrored в зависимости от обстоятельств.

В нашем случае ответ API будет идентичен тому что мы жёстко закодировали в предыдущем примере, но в реальном приложении вы можете получать например список книг, новые записи в блоге, короче то что нужно вашему приложению.

Чтобы получить элементы мы воспользуемся такой штукой, которая называется Fetch API. Fetch позволяет выполнять запросы намного проще чем классический XMLHttpRequest и возвращает промис (который важен для Thunk). Fetch доступен не для всех браузеров, поэтому нам нужно добавить его в зависимости нашего проекта:

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

Вот что у нас получится в итоге (не изменённые строки опущены):

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

Преобразование в Redux

Есть несколько основных принципов в Redux, которые нужно понимать:

, который оборачивает всё наше приложение и передаёт хранилище store всем дочерним элементам.

Всё это должно стать более понятным, когда мы начнем преобразовывать наше приложение в Redux.

Проектирование нашего состояния

Создание наших действий

Два первых создателя действий принимают логическое значение bool (true/false) в качестве аргумента и возвращают объект содержащий type и bool в соответствующих свойствах.

Обратите внимание на то, что значение которое вы используете для свойства type и имя другого свойства возвращаемого объекта очень важны, потому что мы будем использовать их снова в редьюсерах.

Теперь когда у нас есть 3 действия, которые будут представлять наше состояние, мы преобразуем оригинальный метод fetchData() нашего компонента в метод itemsFetchData() нашего создателя действия.

По настоящему простым примером может быть отправка действия itemsHasErrored() через пять секунд.

Создание редьюсеров

С действиями определились, теперь напишем редьюсеры, которые будут брать эти действия и возвращать новое состояние приложения.

Примечание: В Redux всегда вызываются все редьюсеры независимо от того какое действие было отправлено, поэтому внутри каждого из них нужно возвращать оригинал состояния, если не действие не применяется.

Каждый редьюсер принимает два параметра: предыдущее состояние ( state ) и объект действия ( action ).

Если action.type совпадает с текущим действием, то мы возвращаем подходящее свойство этого действия. Как уже говорилось ранее, action.type и action[propertyName] это то, что мы определяли в создателях действий.

Отличается он потому что у него может быть несколько условий, например он может возвращать массив со всеми элементами, а может возвращать какое-то подмножество после того как было отправлено действие «удаления», а может вообще возвращать пустой массив, если были удалены все элементы.

Каждый редьюсер будет возвращать отдельное свойство состояния, не зависимо от того сколько условий в этом редьюсере. Мне нужно было некоторое время, чтобы это понять.

Настройка хранилища и предоставление его приложению

Это довольно просто. Давайте создадим файл store/configureStore.js со следующим содержимым:

Теперь изменим файл index.js нашего приложения и добавим в него

Чтобы добраться до этой стадии нужно приложить совсем немного усилий, и теперь когда мы закончили с настройкой, можно изменить наш компонент чтобы использовать всё то, что уже сделали.

Преобразование компонента для использования Redux хранилища и методов

В верхней части файла нужно изменить секцию import :

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

И нам нужна ещё одна функция, чтобы иметь возможность отправлять наш создатель действий itemsFetchData() со свойством.

Пока что эти 2 функции ничего не делают, так как нам нужно изменить завершающую строку экспорта ( export ).

Эта строка соединяет наш ItemList с Redux, чтобы во время отображение мы могли использовать свойства.

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

Ваш компонент должен выглядеть следующим образом:

Вот и всё. Теперь приложение использует Redux и Redux Thunk для получения и отображения данных.

Это было не так сложно, не так ли?

Теперь вы Redux мастер 😀

Что дальше?

Весь код данного урока я выложил на Github, с коммитами для каждого шага. Я хочу чтобы вы клонировали его, запустили и поняли как он работает, а после этого добавили возможность удаления определённых элементов из списка, основываясь на позициях элемента.

Источник

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

Published on December 1, 2020

Введение

По умолчанию действия Redux обрабатываются синхронно, что представляет проблему для любых нестандартных приложений, которым требуется взаимодействовать с внешними API или использовать побочные эффекты. Redux также позволяет использовать промежуточное ПО между обрабатываемым действием и действием, которое достигает редукторов.

Существует две очень популярные библиотеки промежуточного ПО, поддерживающие побочные эффекты и асинхронные действия: Redux Thunk и Redux Saga. В этой статье мы расскажем о Redux Thunk.

Thunk или преобразователь — это концепция программирования, в которой функция используется для отсрочки оценки или расчета операции.

Redux Thunk — это промежуточное ПО, позволяющее вызывать создателей действий, которые возвращают функцию вместо объекта действия. Эта функция получает метод обработки магазина, который затем используется для обработки регулярных синхронных действий внутри тела функции после выполнения асинхронных операций.

Из этой статьи вы узнаете, как добавить Redux Thunk и использовать его для гипотетического приложения Todo.

Предварительные требования

Данная статья предполагает, что у вас имеются базовые знания по React и Redux. Вы можете посмотреть эту статью, если только начинаете работать с Redux.

Здесь не разъясняются более подробные детали процедуры создания приложения Todo с нуля. Оно представлено как концептуальная основа для разъяснения Redux Thunk.

Добавление redux-thunk

Прежде всего, используйте терминал для перехода в каталог проекта и установите пакет redux-thunk в ваш проект:

Примечание. Redux Thunk содержит всего 14 строк кода. Посмотрите исходный код здесь, чтобы узнать о принципах работы промежуточного ПО Redux.

Итак, мы импортировали Redux Thunk и добавили его в наше приложение.

Использование Redux Thunk в образце приложения

Чаще всего Redux Thunk используется для асинхронного взаимодействия с внешним API с целью получения или сохранения данных. Redux Thunk упрощает обработку действий, сопровождающих жизненный цикл запроса внешнего API.

Для создания нового элемента todo обычно требуется предварительно обработать действие, чтобы обозначить начало создания элемента todo. Затем, если элемент todo успешно создан и возвращен внешним сервером, необходимо обработать другое действие с новым элементом todo. В случае получения ошибки и невозможности сохранения todo на сервере необходимо обработать действие с ошибкой.

Давайте посмотрим, как сделать это с помощью Redux Thunk.

Импортируйте действие в компонент контейнера и обработайте его:

Действие использует Axios для отправки запроса POST на конечную точку в JSONPlaceholder ( https://jsonplaceholder.typicode.com/todos ):

Обратите внимание на то, как создатель действия addTodo возвращает функцию вместо обычного объекта действия. Эта функция получает метод обработки из магазина.

При использовании внешнего API, например, JSONPlaceholder в приведенном примере, может возникнуть реальная задержка сети. Однако, если вы работаете с локальным сервером, ответ сети может быть получен слишком быстро, чтобы получить такую же задержку, с какой столкнется конечный пользователь, так что вы можете добавить искусственную задержку при разработке:

Чтобы протестировать сценарии ошибок, вы можете создать ошибку вручную:

Для полноты приведем пример того, как может выглядеть редуктор todo для обработки полного жизненного цикла запроса:

Изучение getState

После получения метода dispatch от состояния функция, возвращаемая создателем асинхронного действия с Redux Thunk, также получает метод getState магазина, что позволяет прочитать текущие значения магазина:

В вышеперечисленном случае текущее состояние просто распечатывается на консоли.

Использование getState может быть полезно для того, чтобы обрабатывать действия по-разному в зависимости от текущего состояния. Например, если вы захотите ограничить возможности приложения одновременной обработкой только четырех элементов todo, вы можете выполнять возврат из функции, если состояние уже содержит максимальное количество элементов todo:

В вышеуказанном случае приложение сможет работать только с четырьмя элементами todo.

Заключение

В этом учебном модуле мы изучили добавление Redux Thunk в приложение React для асинхронной обработки действий. Это полезно при использовании магазина Redux и внешних API.

Источник

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *