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

Time:01-12

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?

// 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?

CodePudding user response:

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.

  •  Tags:  
  • Related