reactjscomponentsreact-toastify

A global reactJS Function to be called in all components and containers


I have setup a ToastContainer in my main App.js

return (
    <div className='wrapper' style={{height: '100%'}}>
        <ToastContainer
            limit={1}
            containerId={'error'}
            position='bottom-left'
            autoClose={5000}
            hideProgressBar={false}
            newestOnTop={false}
            closeOnClick
            rtl={false}
            pauseOnFocusLoss={false}
            draggable
            pauseOnHover
            theme='light'/>
        <BrowserRouter>
            <Switch>
                <Route exact path='/' component={() => (renderComponent(view.type))} />
            </Switch>
        </BrowserRouter>
    </div>

And I have an errorHandler function as well

const errorHandler = () => {
    toast.error(<ErrorToast
        errorUUID={localStorage.getItem('errorUUID')}/>, {containerId: 'error', toastId: 'error'});
}

I have about 1000+ components in my application and almost all of them have a renderData async function that does component-specific fetch calls.

What I want to do, is use this error handler function as the primary error function that is used to handle all async fetch calls that are made in all these different classes.

My options as I see them: -

1) Create a ToastContainer for every component that needs it -

Problem -

a) messy code

b) changing the errorHandler from ToastContainer to something else in the future would be a big pain

c) one page could have multiple error toasts that show up in a situation where the fetch call is from the same backend service in separate containers.

2) Pass the errorHandler as a prop to all children, and do a callback

Problem -

a) messy code

b) Ensuring that I pass this errorHandler to every component wherever it is used is bound to fail at some point

c) Will have to maintain this practice of passing errorHandler to all future components

What I want to know is -

Am I doomed to use one of these two methods, or is there a method that I have not yet considered? And if so, what is it, and what are the pros/cons of it?


Solution

  • I tried to do iHelidor's suggestion, but having had no experience with Redux, it was becoming a bit of a challenge. Halfway through I realized that there is a simpler answer.

    I cannot say if this is the best method, but at the very least, I do not have to worry about transferring this function to all children components everywhere they are called.

    Step 1 -

    Shift The return Component in App.js to a const

    const App = <div className='wrapper' style={{height: '100%'}}>
        <ToastContainer
            limit={1}
            containerId={'error'}
            position='bottom-left'
            autoClose={5000}
            hideProgressBar={false}
            newestOnTop={false}
            closeOnClick
            rtl={false}
            pauseOnFocusLoss={false}
            draggable
            pauseOnHover
            theme='light'/>
        <BrowserRouter>
            <Switch>
                <Route exact path='/' component={() => (renderComponent(view.type))} />
            </Switch>
        </BrowserRouter>
    </div>
    

    Step 2 -

    Export the function and component as a list

    return [
        App,
        errorHandler
    ];
    

    Step 3 -

    Create a Simple ErrorHandler component

    class ErrorHandler extends React.Component {
        constructor(props) {
    
            super(props);
            this.app = new App();
        }
    
        handleError() {
            this.app[1]();
        }
    }
    
    export default ErrorHandler;
    

    Step 4 -

    Import the Error Handler and use it

    import ErrorHandler from '@Root/ErrorHandler';
    ...
    ...
    const errorHandler = new ErrorHandler();
    ...
    ...
    errorHandler.handleError();