William
William

Reputation: 4578

React Redux: How to share data between reducers?

I have a basic todo list. The todo input field for the todo list has an 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.

When the user submits the form I want to get the data that was previously stored via the onChange event, then I want to place it on a new property on the store object.

How do I get data that was previously entered from the store and pull it into a different reducer?

In all the examples I've seen, reducers start with an "initial state". I don't want that, I want the previous state that the user entered.

Below is a CodeSandbox version of the code (for some reason the orange-beige tab to the right needs to be switch to the left to blue for it to render the form. If you don't do that it won't work).

https://codesandbox.io/s/pwqlmp357j

Upvotes: 4

Views: 6035

Answers (4)

Shivam
Shivam

Reputation: 3131

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

Well if we talk about correctly structuring the reducer, cachedInput and todoList should live in single reducer. There is no need to create another reducer. Also I guess you need to grab the input value all at once(when user clicks on submit) and send it to store.

If still you want to create seperate reducers then you can follow the approach given below :

Answer to How to access or share data already in store, inside the reducers?

Don't use combineReducers.

Example

replace this code

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

with

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

reducer would be like

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

and you can access the previous state from root

Upvotes: 7

alireza
alireza

Reputation: 546

If you want to load your application with initial state that contains previously cached data and if you are using client side rendering, you may insert cached data in redux store into local storage and use that as initial state.

If you just want data to be imported to the other reducer after form submission, you may use redux-thunk. It lets you load current state in your submit action and pass the catches values into the other reducer and store them.

if you are using ssr and you want data be loaded on server there is no way unless saving data on server ( in a file or database), read the data when request is received on server and update your redux store. It will load data all over your app.

Upvotes: 0

Hriday Modi
Hriday Modi

Reputation: 2081

You are using two different state(or say initialState) for each reducer. Hence update in one object is not reflecting in the other.

You need to use the shared initialState for both of the reducer and your problem is solved.

You can keep initialState in different file and you can import in both the reducers.

Consider below code sample:

1.InitialState.js

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

2.Now in CachDataOfTodoInput.js

import initialState from "InitialState";

export function cachInput(state = initialState, action)

3.Same in SubmitDataToTodo.js

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

Hence intialState is shared between your reducers and you will be able to access data in each reducer.

Upvotes: 1

RIYAJ KHAN
RIYAJ KHAN

Reputation: 15292

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

Practically, this is not right way to use to redux->action->reducers->store considering you are submitting the form to send the same data to reducers.

This will caused un-necessary rendering of component connected with redux#connect if you have not handled shouldComponentUpdate /componetWillRecieve/getDerivedStateFromProps nicely

Instead store the each character/string that you typed, inside component state and once the user submit it, dispatch the action to pass the string/characters to reducer's.

Upvotes: 2

Related Questions