Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

React attempting to replace view, appending instead

I am attempting to make a simple navigation where I am lazily importing views and replacing the "target" with whatever view is selected … The problem is that my solution APPENDS my view to <MainView /> instead of replacing <MainVies />‘s content.

I initially thought about doing something like This Question — But from what I understand it will import all the views at application load, and you will need to do a full refresh to "re-import" the views ..

import React, {lazy, useState} from 'react';

const importView = viewName =>
    lazy(() =>
        import(`../../layout/views/${viewName}`)
            .catch(() => import(`../../layout/views/Dashboard`))
    );

const MainView = ({views}) =>
    Object.values(views).map(View => (
        <View/>
    ));

export default function App() {
    const [views, setView] = useState({});

    const changeView = viewName => {

        // For debugging if set
        //if (views[viewName]) return;

        const View = importView(viewName);
        setView(c => (
                {...c, [viewName]: View}
            )
        );
    };

    const loadDashboard = () => changeView('Dashboard');
    const loadInbox = () => changeView('Inbox');
    const loadNewsletters = () => changeView('Newsletters');

    return (
        <main>
            <section>
                <button
                    onClick={loadDashboard}>
                    Dashboard
                </button>
                <button
                    onClick={loadInbox}>
                    Inbox
                </button>
                <button
                    onClick={loadNewsletters}>
                    Newsletters
                </button>
            </section>
            <section>
                <React.Suspense fallback="Loading view...">
                    <div className="row">
                        <MainView views={views}/>
                    </div>
                </React.Suspense>
            </section>
        </main>
    );
}

This works .. Except it is appending to the view rather than replacing the view. I am looking to use this as navigation, so I need it to replace the view completely .. I want it to work like standard navigation, switching between views, and import the view every time the button is clicked (in case a view like Inbox has changed, it will import with the updated Inbox view on button click)

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

What am I doing wrong here?

>Solution :

You can use the state to control the view name, then use a function to render the current view.

import React, {lazy, useState} from 'react';

const importView = viewName =>
    lazy(() =>
        import(`./${viewName}`)
            .catch(() => import(`./Dashboard`))
    );

export default function App() {
    const [view, setView] = useState(null);


    const loadDashboard = () => setView('Dashboard');
    const loadInbox = () => setView('Inbox');
    const loadNewsletters = () => setView('Newsletters');

    const renderCurrentView = () => {
      const View = importView(view);

      return <View />
    }

    return (
        <main>
            <section>
                <button
                    onClick={loadDashboard}>
                    Dashboard
                </button>
                <button
                    onClick={loadInbox}>
                    Inbox
                </button>
                <button
                    onClick={loadNewsletters}>
                    Newsletters
                </button>
            </section>
            <section>
                <React.Suspense fallback="Loading view...">
                    <div className="row">
                        {renderCurrentView()}
                    </div>
                </React.Suspense>
            </section>
        </main>
    );
}
Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading