React Redux: как обмениваться данными между редукторами?

У меня есть базовый список дел. В поле ввода todo для списка todo есть событие onChange, которое запускает действие и отправляет event.target.value редуктору и сохраняет каждый вводимый пользователем символ в свойстве объекта store.

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

Как мне получить данные, которые были ранее введены из магазина, и перенести их в другой редуктор?

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

Ниже представлена ​​версия кода CodeSandbox (по какой-то причине оранжево-бежевая вкладка справа должна быть переключена влево на синий, чтобы она отображала форму. Если вы этого не сделаете, это не сработает).

https://codesandbox.io/s/pwqlmp357j

Пожалуйста, напишите код в самом SO, потому что в будущем ссылка может сломаться.

Shivam 11.06.2018 09:46
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
В настоящее время производительность загрузки веб-сайта имеет решающее значение не только для удобства пользователей, но и для ранжирования в...
Безумие обратных вызовов в javascript [JS]
Безумие обратных вызовов в javascript [JS]
Здравствуйте! Юный падаван 🚀. Присоединяйся ко мне, чтобы разобраться в одной из самых запутанных концепций, когда вы начинаете изучать мир...
Система управления парковками с использованием HTML, CSS и JavaScript
Система управления парковками с использованием HTML, CSS и JavaScript
Веб-сайт по управлению парковками был создан с использованием HTML, CSS и JavaScript. Это простой сайт, ничего вычурного. Основная цель -...
JavaScript Вопросы с множественным выбором и ответы
JavaScript Вопросы с множественным выбором и ответы
Если вы ищете платформу, которая предоставляет вам бесплатный тест JavaScript MCQ (Multiple Choice Questions With Answers) для оценки ваших знаний,...
2
1
3 483
4

Ответы 4

Вы используете два разных состояния (или, скажем, initialState) для каждого редуктора. Следовательно, обновление в одном объекте не отражается в другом.

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

Вы можете сохранить initialState в другом файле, и вы можете импортировать его в оба редуктора.

Рассмотрим ниже пример кода:

1.InitialState.js

export default initialState = {
  todoList: [
    { text: "fake todo" },
    { text: "fake todo" },
    { text: "fake todo" }
  ],
  cachedInput: ""
};

2.Теперь в CachDataOfTodoInput.js

import initialState from "InitialState";

export function cachInput(state = initialState, action)

3. То же в SubmitDataToTodo.js

import initialState from "InitialState";
export function submitNewTodo(state = initialState, action)

Следовательно, intialState совместно используется вашими редукторами, и вы сможете получить доступ к данным в каждом редукторе.

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

William 11.06.2018 07:53

Кажется, что это будет работать, но все еще не ясно, является ли это правильной практикой и т. д.: «Вы можете сохранить initialState в другом файле, и вы можете импортировать его в оба редуктора».

William 11.06.2018 07:58

Это правильная практика в redux. Основное различие между потоком и редукцией заключается в том, что у потока может быть несколько хранилищ, в то время как в редукции вы должны объявить одно хранилище. Просмотрите ответ на этот вопрос, чтобы узнать разницу: stackoverflow.com/questions/32461229/…

Hriday Modi 11.06.2018 08:04

Согласитесь с Хридаем, у redux должен быть один магазин.

Vivek 11.06.2018 08:25

Я попытался последовать твоему предложению, и когда я отправляю задачи, они остаются пустыми. CachedData не хранится в другом свойстве объекта. Пример: codeandbox.io/s/6z8vno7vo3

William 11.06.2018 10:51

Вы не импортировали initialState в CachDataOfTodoInput.js. Пожалуйста, проверьте код правильно.

Hriday Modi 11.06.2018 10:58

На моем локальном компьютере это не работает .... Я обновил проблему в онлайн-приложении, теперь контент не отображается. codeandbox.io/s/187z1m6n93

William 11.06.2018 20:16

К сожалению, приложение не сохраняет мои изменения. Здесь: codeandbox.io/s/wq1nvjz3wk

William 11.06.2018 20:18

Вы не возвращаете новые объекты из редукторов. Это считается плохим?

William 11.06.2018 21:19

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

Hriday Modi 11.06.2018 21:32

onChange event that triggers an action and sends event.target.value to a reducer and stores each character the users types to a property of the store object

На практике это неправильный способ использования redux->action->reducers->store, учитывая, что вы отправляете форму для отправки тех же данных редукторам.

Это приведет к ненужному рендерингу компонента, связанного с redux#connect, если вы неправильно обработали shouldComponentUpdate /componetWillRecieve/getDerivedStateFromProps

Вместо этого сохраните каждый набранный вами символ / строку внутри компонента state, и как только пользователь отправит его, dispatch в action для передачи строки / символов в reducer's.

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

William 11.06.2018 07:56

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

devserkan 11.06.2018 07:58

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

Если вы просто хотите, чтобы данные были импортированы в другой редуктор после отправки формы, вы можете использовать redux-thunk. Он позволяет загружать текущее состояние в действие отправки и передавать значения перехвата в другой редуктор и сохранять их.

если вы используете ssr и хотите, чтобы данные загружались на сервер, нет никакого способа, кроме сохранения данных на сервере (в файле или базе данных), прочитать данные, когда запрос получен на сервере, и обновить ваше хранилище redux. Он загрузит данные по всему вашему приложению.

Ask yourself whether you've structured your reducers correctly. If a and b are not independent of one another, why are they separate reducers?

Что ж, если мы говорим о правильном структурировании редуктора, cachedInput и todoList должны жить в одном редукторе. Нет необходимости создавать другой редуктор. Также я предполагаю, что вам нужно получить все входное значение сразу (когда пользователь нажимает кнопку отправки) и отправить его в хранилище.

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

Ответ на Как получить доступ или поделиться данными, уже хранящимися в хранилище, внутри редукторов?

Не используйте combReducers.

Пример

замените этот код

export const a = combineReducers({
  cachInput,
  newTodo
});

с участием

export default (state = {}, action) => {
  return {
    cachInput: cachInput(state.app, action, state),
    newTodo: newTodo(state.posts, action, state),
  };
};

редуктор был бы похож

const reducer = (state = initialState, action, root) => {....}

и вы можете получить доступ к предыдущему состоянию из root

Другие вопросы по теме