Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Storing "global" object outside of Redux store in React/Redux app

I am building a React/Redux app that needs a globally available object (a websocket lib instance). I originally tried to store this in the Redux state tree, however, the instance is not immutable and it caused lots of problems with hot reloading during development (tons of circular reference errors that don't exist when running from compiled code).

My question is how to store/create this instance so that it is available to my Redux code and React components? I could create it at the very top of the component tree and pass it down the tree as a prop, but that feels very "dirty" after doing everything with react-redux connect.

Is there a better way to do this?

like image 892
Steven Musumeche Avatar asked May 14 '16 02:05

Steven Musumeche


People also ask

Should I keep all component's state in Redux store?

Some users prefer to keep every single piece of data in Redux, to maintain a fully serializable and controlled version of their application at all times. Others prefer to keep non-critical or UI state, such as “is this dropdown currently open”, inside a component's internal state. Using local component state is fine.

How do I get data from Redux outside component?

You just need to export the store from the module where it created with createStore() . Also, it shouldn't pollute the global window object.

What is the best way to access Redux store outside a React component?

You can use store object that is returned from createStore function (which should be already used in your code in app initialization). Than you can use this object to get current state with store. getState() method or store. subscribe(listener) to subscribe to store updates.

Is Redux store global?

With Redux, state is stored globally and can easily be updated or invoked from anywhere in the app.


2 Answers

@sheeldotme's answer will work well if you're using thunks.

Also keep in mind that, depending on the websocket lib you're using, you may not need the instance as a global variable. For example, with socket.io-client, after your initial io(url) call that makes the websocket connection, any subsequent calls to io(url) (with the same url argument) will return that same connection (i.e. socket object) from memory, without having to reconnect. It makes it easy to have an API that you can simply import/require, rather than having to pass the instance around or make it global. See the socket.io docs for more info.

For example:

socket.js

import io from 'socket.io-client'
const socket = io(`${protocol}//${hostname}:${port}`)
export default socket

Now you can simply import/require your socket.js file to have easy access to the same socket object from anywhere.

like image 51
Shane Cavaliere Avatar answered Nov 13 '22 16:11

Shane Cavaliere


Redux Thunk, authored by gaeron, he who authored redux, since 2.1.0 allows you to do:

const store = createStore(
  reducer,
  applyMiddleware(thunk.withExtraArgument(api))
)

// later
function fetchUser(id) {
  return (dispatch, getState, api) => {
    // you can use api here
  }
}

This is straight from the docs, see the link below for more information:

https://github.com/gaearon/redux-thunk

like image 24
sheeldotme Avatar answered Nov 13 '22 15:11

sheeldotme