首页 > 解决方案 > 在 React 中管理共享/单例客户端对象

问题描述

我正在接受一些模式指导。我正在将 React 前端(使用 NextJS)编写到依赖于单例客户端对象的后端(基于 FeathersJS)。在树的上下许多不同的组件中都需要客户端,基本上是为了向服务器发出各种请求。

在网上的简单示例中,该client对象作为共享全局对象进行管理,在需要的地方导入。

// client.js

import io from 'socket.io-client';
import feathers from '@feathersjs/client';

const socket = io();
const client = feathers();

client.configure(feathers.socketio(socket));
client.configure(feathers.authentication());

export default client;

// consumer somewhere

import client from './client';
client.doStuff()

这样做的问题是全局初始化与 webpack 和服务器端渲染的交互很糟糕,通常在全局范围内进行这样的初始化感觉是错误的。

你最好把它放在哪里,以便(a)它早期初始化但只在客户端;(b) 从组件树上下的组件是否容易掌握和使用?

一种选择显然只是管理一个在首次使用时按需初始化的全局单例:

let client = null;

function getClient() {
    global client;
    if(client === null) {
        // initialise client
    }
    return client;
}

但我想知道 React 中是否有更规范的方式,例如使用上下文?

标签: reactjsnext.js

解决方案


在树的上下许多不同的组件中都需要客户端......但我想知道 React 中是否有更规范的方式,例如使用上下文?

我认为 React Context 对这些类型的单例对象很有用,特别是如果该对象将在三个上下的许多地方使用时。在实践中有很多很多这样的例子。我认为自己是一个明智的上下文用户,我会说这就是 Context API 的设计目的。例如,采取useApolloClient. 它使用一个 Apollo 客户端,该客户端之前由 an 放入上下文中,ApolloProvider以便它可以在树中的任何地方使用。

这样做的问题是全局初始化与 webpack 和服务器端渲染的交互很糟糕......你最好把它放在哪里,以便(a)它早期初始化但只在客户端;(b) 从组件树上下的组件是否容易掌握和使用?

是的,在服务器端的渲染树中初始化这些对象可能很棘手或很糟糕。如果您使用的是 Next.js 之类的东西,那么在渲染树“上方”初始化这些对象是有意义的,无论是在顶级模块范围内还是在getInitialProps.


推荐阅读