Home > Enterprise >  How to block UI in React
How to block UI in React

Time:05-19

I have a sync popup when I click "Yes", the client queries the server and the isLoading variable is set to true and the brake appears. During synchronization, I want my user interface to be blocked, for example, when the user clicks somewhere in the component, nothing to happens, but I want the user interface to be visible. Is it possible only with reactjs, html and css or do I have to use some kind of library? If there is any way without a library I want it this way.

This is my code:

const Contact = () => {
const location = useLocation();
const navigate = useNavigate();
const [page, setPage] = useState(0);
const [entry, setEntry] = useState([]);
const [isLoading, setIsLoading] = useState();
const [contacts, setContacts] = useState([]);
const [searchTerm, setSearchTerm] = useState('');
const [countOfContacts, setCountOfContacts] = useState(0);
const [isSynchronizedClicked, setIsSynchronizedClicked] = useState(false);

const synchronize = async () => {
    requester(urls.synchronize, methods.get)
        .then(() => {
            setIsLoading(false);
            navigate(urls.mainPage);
            setIsSynchronizedClicked(false);
        })
        .catch((e) => {
            <Alert severity="error">
                <AlertTitle>Error</AlertTitle>
                The synchronization is not successful.
            </Alert>
            console.log(e.message);
        });
};

return (
    <>
        <div className='button-search-bar-container'>
            <div className='overview-buttons-container'>
                <button className='buttons overview-synchronize-button' type="submit" onClick={() => setIsSynchronizedClicked(true)}><SyncIcon /> Synchronize</button>
        </div>
        <div style={{ height: 630, width: '100%' }}>
            <DataGrid
                id={contacts.map((contact) => contact.id)}
                rows={contacts}
                loading={isLoading}
                paginationMode='server'
            />
        </div>
{isSynchronizedClicked && <ClickAwayListener onClickAway={() => setIsSynchronizedClicked(false)}>
            <div className='popup synchronize-popup'>
                Do you want to synchronize all contacts ?
                <div className='second-message'>This will take a while.</div>
                <div className='synchronize-popup-buttons-container'>
                    <button className='buttons reject' onClick={() => setIsSynchronizedClicked(false)}>No</button>
                    <button className='buttons approve' onClick={() => { synchronize(); setIsLoading(true); setIsSynchronizedClicked(false); }}>Yes</button>
                </div>
            </div></ClickAwayListener>}
    </>
);
};

CodePudding user response:

You can return early from a component. Add the following snippet (change the logic as you want, specifically I have not added handling of error within synchronize):

 [...]

 if (isLoading) {
     return null;
 }

return <> 
  // existing component
</>
 [...]

Moreover, I don't see synchronize() being called anywhere. You need to introduce a useEffect to call synchronize() within the component.

CodePudding user response:

I make it like that in the .css file

.disabled {
opacity: 0.4;
pointer-events: none;

}

and in my component:

<div className={isLoading ? 'disabled' : ''}>
<Component />
</div>
  • Related