Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Sharing global/singleton data in react app

I'm rewriting a small app to try and better understand React. I'm trying to determine the "correct"/most efficient method of sharing "singleton" data - for example, a user who's been properly authenticated upon login.

Right now the parent "application" component has a user property in its state, which I pass to child components as a prop:

<Toolbar user={this.state.user} />
<RouteHandler user={this.state.user}/>

(I'm using react-router). This works, and in read-only cases like this, isn't terrible. However, my actual login form component (which is a route, and would be inside RouteHandler), needs some way to "set" the new user data, so I also need to pass in some callback:

<RouteHandler onAuthenticated={this.setUser} user={this.state.user}/>

Not a big problem, except for the fact that now this method is available to every "route" handled by RouteHandler.

I've been reading up and it seems like the only alternative is an EventEmitter or Dispatch-style system.

Is there a better way I'm missing? Is an event emitter/dispatcher system worth using when there's really only one or two uses in an app this small?

like image 673
helion3 Avatar asked Jun 30 '15 05:06

helion3


People also ask

How do I use singleton in react?

To use react-redux or any other context-based functionality, singleton hooks should be mounted under provider in your app. To do that, import SingletonHooksContainer from react-singleton-hook and mount anywhere in you app. SingletonHooksContainer must be rendered ealier then any component using singleton hook!

Is react State a singleton?

In React, we often rely on a global state through state management tools such as Redux or React Context instead of using Singletons. Although their global state behavior might seem similar to that of a Singleton, these tools provide a read-only state rather than the mutable state of the Singleton.

Is react context a singleton?

React Context is a way to make an object available in all components of my React tree without having to thread the object through the props of intermediary components. ES6 modules also offer a simple way to make a singleton global object.

What is dependency injection react JS?

Dependency injection (DI) is a pattern where components necessary for your code to run are hot-swappable. This means that your dependencies are not hard-coded in your implementation and can change as your environment changes.


1 Answers

React Context provides a way to pass data through the component tree without having to pass props down manually at every level. With context, every component nested under a Provider has access to the data, but you need to explicitly read the value.

I recommend using React Hooks with useContext. One way to do this would be to set the value of the context to be an object with setter and getter functions.

import React, { useState, useContext } from "react"

export const UserContext = React.createContext({}); //Initialise

//Wrapper with getter and setter 
const App = () => {
    const [user, setUser] = useState();
    const value = {user, setUser}
    return (
        <div>
            <UserContext.Provider value={value}>
                <RouteHandler/>
                <AnotherComponent/>
            </UserContext>
            <ComponentWithoutAccessToUserContext/>
        </div>
    )
}

const RouteHandler = (props)=> {
   const { user, setUser } = useContext(UserContext)
   // This component now has access to read 'user' and modify it with 'setUser'


}

const AnotherComponent = () => {
   return (<div>Component which could be get access to the UserContext</div>)
}
like image 59
Manoj Kurien Avatar answered Oct 05 '22 23:10

Manoj Kurien