使用 Redux Toolkit,如何从非反应文件访问商店?

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

我想做什么?

使用 Redux Toolkit,我试图从一个名为 SomeFile.js 的非 React 文件访问一个值的“存储”,特别是我为其创建了一个“切片”的“用户名” .

目前尝试这样做的代码是什么?

// 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.
}

我期望结果是什么?

能够从“商店”中提取用户名。

实际结果如何?

当我尝试通过非反应文件中的“useSelector”访问值时发生错误:React Hook "useSelector" is called in function "selectUsername" which is neither a React function component or a custom React Hook function

我认为可能是什么问题?

SomeFile.js 里面没有任何与 React 相关的东西,因为它只是从存储中提取数据并输出数据。

我尝试过的一个有效解决方案是这样做的:

// 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";

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

我正在寻找的解决方案是:

  1. 我提出的解决方案是从非 React 文件中的“商店”接收信息的“正确”方式吗?
  2. 是否有针对此的自定义挂钩解决方案?

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

不,这是在滥用 Hooks 规则和 React 函数。您正在直接调用 SelectUsername React 函数。

Is there a custom hook solution for this?

不,React 挂钩仅在 React 函数和自定义 React 挂钩中起作用。

您可以从您的 Redux store 对象访问您的状态。

Store

从您创建的 store 对象中,您将有一个要调用的 getState 方法。

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.

您可以导出创建的商店对象以导入到非 React JS 文件中,它们可以调用 getStore 方法。

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

...

const state = store.getState();

来自 react-reduxuseSelector React 钩子在 React 组件之外不起作用,但 selectUsername 状态选择器函数可以。

// 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;
};

请参阅其他 Store Methods 从 React 外部订阅状态更改和向您的商店发送操作。