简体   繁体   中英

Should I export singleton class for consumption in React?

I have an AuthService class that provides all the api calls and handles authentication for those calls, so its a nice modular service. It is not a React component and not used in any render calls. It handles fetch calls mostly. In many other classes now, I use a single global instance of this class, and import it at the top.

I don't think a context is the right approach because it's not an object type or used in renders. I use the instance in componentDidMount() and useEffect().

an example:

//at the bottom, outside curly braces defining AuthService
export const Auth = new AuthService();

a consumer:

import React, { Component } from "react";
import ReactDOM from "react-dom";
import { useState, useEffect } from 'react';
import CommentList from "./CommentList";
import CommentForm from "./CommentForm";
import Comment from "./Comment";
import AuthService from './AuthService';
import { Auth } from './AuthService';

export default function CommentBox(props) {

const [comments, setComments] = useState([]);
// const Auth = new AuthService();
const [formText, setFormText] = useState('');
const [update, setUpdate] = useState(false);

useEffect(() => {

    Auth.fetch('/comments/get_comment_for_bill/' + props.id + '/').then((data) => {
        if (typeof data[0] !== 'undefined') {
            setComments(data);
        } else {
            setComments([]);
        }
        setUpdate(false);
    });
    return () => {
        return;
    }
}, [props, update]);

return (
    <div >         
        <CommentList comments={comments}/>
        <CommentForm id={props.id} formText={formText} setFormText={setFormText} setUpdate={setUpdate}
            onChange={e => {
                setFormText(e.target.value);                  
            }} />           
    </div>

);
}

I think the best approach to using singletons in React is by attaching it to the window object. Just make sure you first attach the singleton to an object, which in turn is attached to the window object - to avoid polluting your window namespace. You would do this attaching in your startup script only once:

index.js

var window.app = {}
window.app.authentication = (function() {
   function authenticateUser(userId) {

   }

   return {
      authenticateUser: authenticateUser
   }
})();

Then in some other module where you want to use it:

Login.js

window.app.authentication.authenticateUser("johndoe");

It's just fine. There's nothing wrong. But why use same instance for everything?

new AuthService()

I would recommend you to export AuthService . Then, whenever you'll need to use that service, define a new instance and use:

const Auth = new AuthService()
// now, use Auth

It's just a personal choice.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM