在 React 组件之间共享类实例对象

afr*_*pan 5 javascript typescript reactjs redux react-redux

比如说,如果我有一个使用单例模式实现的网络管理器类。

export default class Manager {
   private static _Instance: Manager;
   public static get Instance(): Manager {
      if (Manager._Instance) {
         return Manager._Instance;
      } else {
         return new Manager();
      }
   }

   constructor() {
      if (Manager._Instance) {
         return Manager._Instance;
      }
      Manager._Instance = this;
   }

   // Network management methods, etc.
}
Run Code Online (Sandbox Code Playgroud)

我在 React 应用程序组件树的最顶部(应用程序生命周期的开始)实例化它:

import React from 'react';
import { BrowserRouter as Router, Switch, Route } from 'react-router-dom';
import Manager from './Manager';
import Foo from './Foo';
import Bar from './Bar';

class App extends React.Component<{}, State> {
   private networkManager = new Manager();

   constructor(props: any) {
       super(props);
       this.state = {
           connected: false,
           id: '',
       };
   }

   componentDidMount = (): void => {
       this.initNetwork();
   };

   initNetwork = async (): Promise<void> => {
      try {
         // network management init and config
      } catch(err) {
         // handle network init errors 
      }
   }

   render = (): JSX.Element => {
        return (
            <div className="App">
                <Router>
                    <Switch>
                        <Route
                            path="/foo"
                            render={(props): JSX.Element => (
                                <Foo {...props} NetworkManager={this.networkManager} />
                            )}
                        />
                        <Route
                            path="/"
                            render={(props): JSX.Element => <Bar {...props}/>}
                        />
                    </Switch>
                </Router>
            </div>
        );
    };
}
Run Code Online (Sandbox Code Playgroud)

然后我想在子组件中使用该实例,显然我有几种方法可以做到这一点,但最好的方法是什么?我可以将它作为 prop 传递给组件,或者导入它并使用实例属性来获取实例。两种方法的优点和缺点?

import React from 'react';

type Props = {
    networkManager: Manager;
};
class Foo extends React.Component<Props> {
   private manager: Manager;
   constructor(props) {
      super(props);
      this.manager = props.networkManager;
   }
}

// alternatively in ./Bar.tsx
import React from 'react';
import Manager from './Manager';

class Bar extends React.Component {
   private manager: Manager
   constructor(props) {
      super(props);
      this.manager = Manager.Instance; // new Manager() should also return the same instance
   }
}
Run Code Online (Sandbox Code Playgroud)

还有另一种我不知道的更好的方法吗?像 Redux 这样的东西会很好,但我的经验是存储普通的对象文字而不是类实例,并且将这样的东西放在存储中似乎并不正确。我如何共享实例真的很重要吗?两者都通过 props 传递并导入工作,并且在所需的输入量方面大致相当。在性能方面,我认为也没有太大区别,实例永远不应该改变,因此道具永远不会更新并触发组件重新渲染,但这可能是需要考虑的事情。是我想太多了吗?