Daniel Reina
Daniel Reina

Reputation: 6407

What's the alternative to store a function in a Redux store

Problem

I have a structure like this:

<MenuBar />
<NavigationBar>
  <irrelevant stuff here />
  <ActionButton />
</NavigationBar>
<Router>
  <Route ...>
</Router>

And I want the ActionButton in the NavigationBar to do something different depending on what Route is rendered by the Router (a standard ReactRouter Router)

First thought

My first thought was to save a function on the store and using mapStateToProps and connect, send that function as a prop to the ActionButton. I would dispatch an action with the function as payload whenever the callback should change.

I'm pretty sure that should work, but I know storing non-serialisable stuff in the store can have negative consequences. In particular it gives problems with persisting and rehydrating the contents of a store, as well as interfering with time-travel debugging. This link from the docs talks about it and has a reference to some GitHub issues where that is discussed.This StackOverflow question also discuss the issue.

Question

I've seen many places where people say "you shouldn't do that", but I haven't seen an alternative to storing a function in the store yet. The alternative that I can think of is using props drilling, but I would really like to avoid that pattern.

At this point I don't really need to persist or rehydrate the store, and time-travel debugging is a very nice to have but not a must-have. However, I'd like to avoid sacrificing those things if there's a good alternative.

Thanks in advance! :)

Upvotes: 0

Views: 2414

Answers (2)

Sam Chen
Sam Chen

Reputation: 157

You could put the state of react-router in your redux store. Then when navigation state changes, you can access the current route from within the NavigationBar or the ActionButton.

You could store logic for deciding what the button does based on the route in the ActionButton or the NavigationBar.

Upvotes: 0

markerikson
markerikson

Reputation: 67607

A couple options:

  • Use a middleware to listen for an "ACTION_BUTTON_CLICKED" action, and run different logic based on other values (store state, route, etc). This could be a custom middleware you've written yourself, or a general-purpose side effects middleware like redux-saga or redux-observable that lets you respond to dispatched actions.
  • Put a predefined action into the store based on other behaviors, and have that action be dispatched when the button is clicked.

I show an example of the predefined action approach in my post Practical Redux, Part 10: Managing Modals and Context Menus.

Upvotes: 2

Related Questions