Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

Using Redux Toolkit, how do I access the store from a non-react file?

What am I trying to do?

Using Redux Toolkit, I’m trying to access the "store" for a value, specifically "username" which I’ve created a "slice" for, from a non-React file called SomeFile.js.

What is the code that currently tries to do that?

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

// userMetadataSlice.js

import { createSlice } from "@reduxjs/toolkit";

const initialState = {
  username: "",
};

const userMetadataSlice = createSlice({
  name: "userMetadata",
  initialState,
  reducers: {
    updateUsername: (state, action) => {
      const username = action.payload;
      state.username = username;
    },
  },
});

export const { updateUsername } = userMetadataSlice.actions;

export default userMetadataSlice.reducer;

export const selectUsername = (state) => {
  return state.userMetadata.username;
}
// SomeFile.js

import { selectUsername } from "../redux/userMetadataSlice";
import { useSelector } from "react-redux";

export const displayUsername = () => {
  const username = useSelector(selectUsername);
  console.log("Username:", username); // Error.
}

What do I expect the result to be?

To be able to pull the username from the "store".

What is the actual result?

When I try to access the value via "useSelector" from the non-react file an error occurs: React Hook "useSelector" is called in function "selectUsername" which is neither a React function component or a custom React Hook function

What I think the problem could be?

SomeFile.js does not have anything React related within it because it just pulls data from the store and outputs the data.

A solution I’ve tried that worked was to do this:

// userMetadataSlice.js

import { createSlice } from "@reduxjs/toolkit";

const initialState = {
  username: "",
};

const userMetadataSlice = createSlice({
  name: "userMetadata",
  initialState,
  reducers: {
    updateUsername: (state, action) => {
      const username = action.payload;
      state.username = username;
    },
  },
});

export const { updateUsername } = userMetadataSlice.actions;

export default userMetadataSlice.reducer;

export const selectUsername = (state) => {
  return state.userMetadata.username;
}

// New code here!

export function SelectUsername() {
  const username = useSelector(selectUsername);
  return username;
}
// SomeFile.js

import { SelectUsername } from "../redux/userMetadataSlice";
import { useSelector } from "react-redux";

export const displayUsername = () => {
  console.log("Username:", SelectUsername); // No errors, shows correct output.
}

The solutions I’m looking for is this:

  1. Is my proposed solution the "proper" way to receive info from the "store" in non-React files?
  2. Is there a custom hook solution for this?

>Solution :

Is my proposed solution the "proper" way to receive info from the
"store" in non-React files?

No, it’s abusing the Rules of Hooks and React functions. You are directly invoking the SelectUsername React function.

Is there a custom hook solution for this?

No, React hooks work only in React functions and custom React hooks.

You can access your state from your Redux store object.

Store

From your created store object you’ll have a getState method to invoke.

getState()​

Returns the current state tree of your application. It is equal to the
last value returned by the store’s reducer.

Returns

(any): The current state tree of your application.

You can export your created store object for import into non-React JS files and they can invoke the getStore method.

import store from '../path/to/store';

...

const state = store.getState();

The useSelector React hook from react-redux won’t work outside a React component, but the selectUsername state selector function will.

// SomeFile.js
import store from '../path/to/store';
import { selectUsername } from "../redux/userMetadataSlice";

...

export const displayUsername = () => {
  const state = store.getState();

  const username = selectUsername(state);

  console.log("Username:", username);

  return username;
};

See the other Store Methods for subscribing to state changes and dispatching actions to your store from outside React.

Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading