2017-01-14 8 views
4

Я пытаюсь сделать несколько изменений в магазине, но не отображать до тех пор, пока все изменения не будут выполнены. Я хотел сделать это с помощью редуктора.React + Redux, как визуализировать не после каждой отправки, но после нескольких?

Вот мое действие Создатель:

function addProp(name, value) { 
    return { type:'ADD_PROP', name, value } 
} 

function multiGeoChanges(...changes) { 
    // my goal here is to make multiple changes to geo, and make sure that react doesnt update the render till the end 
    return async function(dispatch, getState) { 
     for (let change of changes) { 
      dispatch(change); 
      await promiseTimeout(2000); 
     } 
    } 
} 

рассылает мой асинхронные действия создателя, как это:

store.dispatch(multiGeoChanges(addProp(1, "val1"), addProp(2, "val2"), addProp(3, "val3"))); 

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

ответ

4

Есть способы достижения цели:

Классический способ:

обычно: действия описывают факт, что что-то произошло, но не указать, как изменения состояния приложения в ответ. Это работа редукторов. Это также означает, что действия не установлены.

Таким образом, вы могли бы описать то, что произошло, и накапливают изменения и отправки одиндействие что-то вроде:

const multipleAddProp = (changedProps) =>({ 
    type:'MULTIPLE_ADD_PROP', changedProps 
}); 

А затем реагировать на действия в редукторе:

const geo=(state,action)=>{ 
    ... 
    switch (action.type){ 
    case 'MULTIPLE_ADD_PROP': 
    // apply new props 
    ... 
    } 
} 

Другой способ Когда реверсирование имеет решающее значение:

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


Нестандартный способ: redux-batched-action

Он работает что-то вроде сделки.

В этом примере абоненты будут оповещены сразу: ответ

import { batchActions } from 'redux-batched-actions'; 

const multiGeoChanges=(...arrayOfActions)=> dispatch => { 
    dispatch(batchActions(arrayOfActions)); 
} 
+1

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

+0

@Noitidart - thunk действительно очень полезен для получения удаленных данных, особенно если вам нужно сделать несколько звонков от одного действия. – Snekse

+1

Спасибо @Snekse Я использую redux-saga сейчас дни :) – Noitidart

2

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

Вы можете избежать этого, обновив состояние один раз.

Если вы используете обещания, вы можете использовать Promise.all, чтобы дождаться выполнения всех обещаний, а затем отправить новое действие в магазин с вычисленным результатом. https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/Promise/all

Что-то вроде этого:

Promise.all([p1, p2, p3, p4, p5]).then(changes => { 
    dispatch(changes) 
}, err => { 
    // deal with error 
}); 

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

+0

Спасибо Sagi за это, это интересный подход, +1. – Noitidart

6

@Kokovin Владислава правильно. Чтобы добавить дополнительный контекст:

Redux уведомит всех абонентов после каждые. Сократить повторные рендеры, либо отправить меньше раз, либо использовать один из нескольких подходов для «пакетных» рассылок и уведомлений. Для получения дополнительной информации см. FAQ по Redux по вопросам обновления: http://redux.js.org/docs/faq/Performance.html#performance-update-events.

Я также недавно написал пару сообщений в блоге, которые относятся к этой теме. Idiomatic Redux: Thoughts on Thunks, Sagas, Abstraction, and Reusability обсуждает плюсы и минусы использования thunks и суммирует несколько способов обработки пакетных рассылок. Practical Redux Part 6: Connected Lists, Forms, and Performance описывает несколько ключевых аспектов, которые необходимо знать о производительности Redux.

Наконец, есть несколько других библиотек, которые могут помочь в регистрации уведомлений об изменениях в магазине. См. Раздел Store#Store Change Subscriptions моего Redux addons catalog для получения списка соответствующих дополнений. В частности, вас может заинтересовать https://github.com/manaflair/redux-batch, что позволит вам отправлять массивы действий только с одним уведомлением.

+1

Спасибо @markerikson за такие удивительные ссылки! Я читаю их сейчас! Моя самая большая потребность в сокращении - это партия и отправка как одна. – Noitidart

+1

Ваша статья о том, «почему thunks» является удивительным! Мне сложно отвечать на многие месяцы! – Noitidart

+1

Спасибо! Да, как упоминает этот пост, есть действительно четыре или пять различных способов, которыми вы можете выполнить «дозирование», в зависимости от того, как вы хотите его выполнить. Если у вас есть дополнительные вопросы, не стесняйтесь пинговать мне по каналам чатов Reactiflux (http://www.reactiflux.com). Я @acemarke, и обычно там вечером EST США. – markerikson

0

redux-batched-actions Создатель пакетного действия и связанный с ним редуктор более высокого порядка для редукции, который позволяет доставлять уведомления абонентов о наборе действий.