React Native 中的全局状态

IT技术 javascript reactjs react-native redux react-redux
2021-04-13 06:50:02

我正在开发一个 React Native 应用程序。

我想保存登录人员的用户 ID,然后检查用户是否在每个组件中都已登录。

所以我要找的是 cookie、会话或全局状态之类的东西。

我读过我应该使用 Redux,但这似乎过于复杂,而且很难让它与react-navigation. 它迫使我为几乎所有东西定义动作和减速器,尽管我唯一想要的是能够访问所有组件中的单个全局状态/变量。

有没有其他选择,或者我真的应该重新构建我的整个应用程序以使用 Redux?

6个回答

我通常创建一个 global.js 包含:

module.exports = {
   screen1: null,
};

并获取屏幕上状态的值

import GLOBAL from './global.js'

constructor() {

    GLOBAL.screen1 = this;

}

现在你可以像这样在任何地方使用它:

GLOBAL.screen1.setState({
    var: value
});
不是this指react组件吗?如果是这样,更好的名称将是GLOBAL.screen1 = this,因为这是组件并且this.state实际上是指与组件关联的状态。@RaphaelEstrada
2021-05-26 06:50:02
功能组件怎么样
2021-05-30 06:50:02
这是最好的; 不要因为它的简单而低估它。我永远摆弄 Redux 只是为了获得基本相同的功能,但代码增加了 20connect倍,并且使用了很多魔法(这些东西真的很烂)。
2021-06-07 06:50:02
我是新手。你如何用函数组件来做到这一点?
2021-06-13 06:50:02
你能给出更强有力的解释吗?我不确定你在 render(){Global.screen1state = this} 中做什么
2021-06-19 06:50:02

自 React 16.8.0(2019 年 2 月 6 日)以来的更新引入了 Hooks。

使用外部库(如Mobx)不是强制性的Redux(在介绍 Hook 之前,我使用了这两种状态管理解决方案)

您只需使用 10 行Source即可创建全局状态

import React, {createContext, useContext, useReducer} from 'react';
export const StateContext = createContext();
export const StateProvider = ({reducer, initialState, children}) =>(
  <StateContext.Provider value={useReducer(reducer, initialState)}>
    {children}
  </StateContext.Provider>
);
export const useStateValue = () => useContext(StateContext);

使用全局状态扩展您的应用程序:

import { StateProvider } from '../state';

const App = () => {
  const initialState = {
    theme: { primary: 'green' }
  };

  const reducer = (state, action) => {
    switch (action.type) {
      case 'changeTheme':
        return {
          ...state,
          theme: action.newTheme
        };

      default:
        return state;
    }
  };


  return (
    <StateProvider initialState={initialState} reducer={reducer}>
        // App content ...
    </StateProvider>
  );
}

有关详细说明,我建议阅读这个精彩的媒体

上下文用于 ReactJS。
2021-06-20 06:50:02

状态管理方面,有一些Redux 的替代方案我建议你看看 Jumpsuit 和 Mobx。但是不要指望它们比 Redux 更容易。状态管理主要是一件神奇的事情,大部分小发明都发生在幕后。

但是无论如何,如果您觉得需要一些全局状态管理,那么无论是 Redux 还是 Mobx 等,都值得花时间掌握其中一种解决方案。我不建议AsyncStorage为此目的使用任何 hacky。

状态管理本质上并不神奇。它可以非常简单,同时又可以最大限度地发挥作用,而无需在幕后进行任何操作,请参阅@RaphaelEstrada 的上述答案。您建议使用整个代码库,其中大部分您将永远不会使用,当单个 javascript 对象可以同样有效地完成工作时。
2021-05-28 06:50:02
@sooper,这就是为什么我不推荐AsyncStorage.
2021-06-11 06:50:02
AsyncStorage持久性这样组件,我认为 OP 与管理应用程序的状态有关,这些状态通常应该在内存中。
2021-06-20 06:50:02

我通常做这样的全局变量:

我创建了一个 globals.js

module.exports = {
  USERNAME: '',
};

类似的东西来存储用户名然后你只需要导入:

GLOBAL = require('./globals');

如果您想存储数据,假设您想保存用户名,只需执行以下操作:

var username = 'test';
GLOBAL.USERNAME = username;

好了,你只需要在你想要的页面上导入 GLOBAL 并使用它,只需使用if (GLOBAL.username == 'teste').

这种方式是部分好。它仅适用于存储大部分保持不变的内容(例如登录状态)。特别是因为更改这些东西不会重新渲染组件(尽管可以克隆道具)。
2021-06-05 06:50:02
这种方式不能正常工作,也不会触发像这样的变化。状态
2021-06-17 06:50:02

如果您不熟悉(像我一样)并且对第一个答案感到困惑。首先,使用一个组件类

export default class App extends React.Component {

constructor(props) {
  super(props);
  this.state = {
    walk: true
  };
  GLOBAL.screen1 = this;
}

render() {
  return (
    <NavigationContainer>
      <Stack.Navigator>
      {this.state.walk ? (
        <>
          <Stack.Screen name="WalkThrough" component={WalkThroughScreen} />
        </>
      ) : (
        <Stack.Screen name="Home" component={HomeScreen} />
      )}
    </Stack.Navigator>
    <StatusBar style="auto" />
  </NavigationContainer>
 )
}

然后你可以在任何其他组件中做(我的组件在 /components 上,全局在 root 上):

import GLOBAL from '../global.js'

GLOBAL.screen1.setState({walk:false})