У меня есть базовый список дел. В поле ввода todo для списка todo есть событие onChange, которое запускает действие и отправляет event.target.value редуктору и сохраняет каждый вводимый пользователем символ в свойстве объекта store.
Когда пользователь отправляет форму, я хочу получить данные, которые ранее были сохранены с помощью события onChange, а затем я хочу разместить их в новом свойстве объекта хранилища.
Как мне получить данные, которые были ранее введены из магазина, и перенести их в другой редуктор?
Во всех примерах, которые я видел, редукторы начинаются с «начального состояния». Я не хочу этого, я хочу предыдущее состояние, которое ввел пользователь.
Ниже представлена версия кода CodeSandbox (по какой-то причине оранжево-бежевая вкладка справа должна быть переключена влево на синий, чтобы она отображала форму. Если вы этого не сделаете, это не сработает).



![Безумие обратных вызовов в javascript [JS]](https://i.imgur.com/WsjO6zJb.png)


Вы используете два разных состояния (или, скажем, 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 совместно используется вашими редукторами, и вы сможете получить доступ к данным в каждом редукторе.
Исходное состояние в моем коде для данных, которые я изначально кэширую, - это пустая строка. Если я импортирую это в другой редуктор, данные, вводимые пользователем, будут потеряны и заменены пустой строкой. Если вы думаете, что я вас неправильно понимаю, я не смогу понять, пока не увижу пример кода.
Кажется, что это будет работать, но все еще не ясно, является ли это правильной практикой и т. д.: «Вы можете сохранить initialState в другом файле, и вы можете импортировать его в оба редуктора».
Это правильная практика в redux. Основное различие между потоком и редукцией заключается в том, что у потока может быть несколько хранилищ, в то время как в редукции вы должны объявить одно хранилище. Просмотрите ответ на этот вопрос, чтобы узнать разницу: stackoverflow.com/questions/32461229/…
Согласитесь с Хридаем, у redux должен быть один магазин.
Я попытался последовать твоему предложению, и когда я отправляю задачи, они остаются пустыми. CachedData не хранится в другом свойстве объекта. Пример: codeandbox.io/s/6z8vno7vo3
Вы не импортировали initialState в CachDataOfTodoInput.js. Пожалуйста, проверьте код правильно.
На моем локальном компьютере это не работает .... Я обновил проблему в онлайн-приложении, теперь контент не отображается. codeandbox.io/s/187z1m6n93
К сожалению, приложение не сохраняет мои изменения. Здесь: codeandbox.io/s/wq1nvjz3wk
Вы не возвращаете новые объекты из редукторов. Это считается плохим?
Да, вы правы, мы должны вернуть новые объекты из редукторов. Лучше всего писать таким образом, это помогает поддерживать неизменность данных в хранилище. Immutable.js также заботится о том же внутри.
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, вы не должны использовать состояние компонента. Думаю, я не понимаю, каковы правила, но да, в этом есть смысл
Нет, вы можете использовать локальное состояние вместе с Redux. Это хороший пример, где вы можете его использовать.
Если вы хотите загрузить свое приложение с начальным состоянием, которое содержит ранее кэшированные данные, и если вы используете рендеринг на стороне клиента, вы можете вставить кэшированные данные в хранилище 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
Пожалуйста, напишите код в самом SO, потому что в будущем ссылка может сломаться.