Redux: Как инициализировать redux с неизменяемым объектом

Созданный на 20 июн. 2015  ·  26Комментарии  ·  Источник: reduxjs/redux

Возможно ли это или я что-то не так делаю?

let initialState = immutable.fromJS({some_store: "some initial data"});
const redux = createRedux(stores, initialState);
...
export function some_store(state, action) {
    // state is undefined here
}
help wanted question

Самый полезный комментарий

@jsifalda

Плюсы использования Immutable с Redux:

  • Вы не можете мутировать по ошибке
  • Намного более высокая производительность и лучшее потребление памяти с большими массивами и объектами

Минусы использования Immutable с Redux:

  • Новый API для изучения для вашей команды
  • Увеличенный размер пакета
  • Немного сложнее отлаживать

Выбор зависит от вас!

Все 26 Комментарий

Я думаю, что ты хочешь что-то вроде этого

// stores/some-store.js
import Immutable from 'immutable'

const { Map, List, fromJS } = Immutable
const initialState = Map({
  foo: 'bar',
  fooList: List()
})

export function someStore (state = initialState, action) {
  if (action.type === 'FOO') {
    return state.set('foo', fromJS(action.foo))
  }
  if (action.type === 'FOO_LIST') {
    return state.set('fooList', fromJS(action.fooList))
  }

  return state
}

// stores/index.js
export { default as someStore } from './some-store'

// application.js
import * as stores from './stores'

const redux = createRedux(stores)

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

Аргумент initialState предназначен только для использования для регидратации состояния с сервера или localStorage. ( @acdlite , мы могли бы объяснить это в документации.)

Тем не менее, то, что вы пробовали, должно работать. Может кто-нибудь исследовать?

Нет, то, что я пробовал, не работает. Я просто хочу создать исходные данные для всех магазинов в одном месте. Думаю, этого мне делать не следует.

Я просто хочу создать исходные данные для всех магазинов в одном месте. Думаю, этого мне делать не следует.

Тебе решать. Считаю, что исходные данные лучше разделить.

Тем не менее, если что-то не работает, давайте оставим это открытым? Я вернусь на следующей неделе и посмотрю, почему это не сработало.

Проблема заключается в том, что composeStores предполагает, что корневое состояние представляет собой простой объект JS, и получает доступ к свойствам с помощью state[key] , что не удается с помощью Immutable.Map . Я думаю, что это может работать с Immutable.Record поскольку это делает поля доступными через обычные свойства JS.

Однако могут быть и другие места, где он принимает простой объект.

Ой. Отличный улов! Спасибо за объяснение. В этом есть смысл.

Использование соединителей также не удается по той же причине: isPlainObject(Immutable.Record) === false .

@pierregm Это действительно правильно. Если он распределит свойства записи по реквизитам компонентов, это все равно не сработает. Вы должны написать select={state => state.get('something').toJS()} .

Мне удалось заставить его работать вот так,

// store
const initialState = Immutable.fromJS({}).toOrderedMap();

export default function streamStore(state = initialState, action) {
  switch (action.type) {

    case actionTypes.FETCH_STREAM_DONE:
      var streamMap = {};

      for (var i in action.stream_data) {
        var item = action.stream_data[i];
        streamMap[item.id] = item;
      }
      return state.merge(Immutable.fromJS(streamMap).toOrderedMap());

    default:
      return state
  }
};

// select
function select(state) {
  return {stream: state.stream.toList()}
}

Он работает отлично, но в результате происходит повторная визуализация всех элементов в потоке (представление списка). Мне было интересно, как можно реализовать что-то, что сравнивает старое состояние с новым состоянием на уровне хранилища и отменяет необходимость рендеринга каких-либо компонентов прямо здесь, когда нет изменений в данных. NuclearJS делает это с помощью неизменяемых структур. Каким будет рекомендованный способ реализовать что-то подобное в redux?

@owais

Проверьте Reselect: https://github.com/faassen/reselect. Он предоставляет функциональность, аналогичную геттерам NuclearJS.

@gaearon Круто! Отличный разговор в ReactEurope, кстати! Благодарю.

Это моя попытка использовать Immutable.js с redux 1.0.0, https://github.com/gajus/redux-immutable

Хороший @gajus! Тестирую redux-immutable сейчас и мне действительно нравится шаблон https://github.com/gajus/canonical-reducer-composition

Спасибо @chiplay. Буду очень признателен за обратную связь, если вы обнаружите недостатки или у вас появятся идеи по улучшению.

есть ли преимущество использования неизменяемых структур вместе с redux? когда сокращение основано на неизменном поведении (например, магазины возвращают новую копию состояния)? Производительность (есть тесты?)? или что-то другое? Спасибо

@jsifalda

Плюсы использования Immutable с Redux:

  • Вы не можете мутировать по ошибке
  • Намного более высокая производительность и лучшее потребление памяти с большими массивами и объектами

Минусы использования Immutable с Redux:

  • Новый API для изучения для вашей команды
  • Увеличенный размер пакета
  • Немного сложнее отлаживать

Выбор зависит от вас!

@gaearon
Большое спасибо за быстрый и полезный ответ!

Если вы хотите, чтобы ImmutableJs и Redux соответствовали стандартам Redux, вы можете взглянуть на https://github.com/indexiatech/redux-immutablejs ,

@gaearon Можно ли разместить ссылку на сайте?

Спасибо, Асаф. Я уверен, что люди найдут это полезным.

4 сентября 2015 г. в 18:36 Асаф Шакарчи [email protected] написал:

Если вы хотите, чтобы ImmutableJs и Redux соответствовали стандартам Redux, вы можете взглянуть на https://github.com/indexiatech/redux-immutablejs ,

@gaearon Можно ли разместить ссылку на сайте?

-
Ответьте на это письмо напрямую или просмотрите его на GitHub.

@asaf

Хороший материал, не хотели бы вы устроить пиар Ecosystem.md ?
Я с радостью добавлю его туда, если вы добавите тесты в свой проект.

@gaearon Завершено модульными тестами, PR: https://github.com/rackt/redux/pull/707

Благодаря!

Привет всем,
небольшой вопрос для @gaearon , из быстрых тестов, которые я провел до сих пор, чтобы реализовать ImmutableJS в моем существующем приложении React / Redux, он кажется немного медленнее: - / но, возможно, я что-то делаю не так ...

Базовый вариант использования: получение набора данных из вызова API и сохранение его в редукторе ...

Из моего редуктора,
Без ImmutableJS:

const initialStore = {
    isLoading : false,
    error     : null,
    data      : []
}

// in the switch case
return {
   ...state,
   isLoading: false,
   error: null,
   data: action.result
}

С ImmutableJS

const initialStore = Map({
    isLoading : false,
    error     : null,
    data      : List()
})

// in the handler function
return state.merge({
    isLoading: false,
    error: null,
    data: List(result.result)
})

Мне интересно, не стоит ли здесь «лечение» ImmutableJS больше?

Насколько я понимаю, от неизменяемости польза больше, когда рендеринг происходит быстро, верно?

Спасибо за ваш отзыв.

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

Хорошо спасибо.
Значит, у меня все равно правильный подход?

Да, мне нравится.

Пока что компромисс того стоил .. 💯

Была ли эта страница полезной?
0 / 5 - 0 рейтинги