Home > other >  React attempting to replace view, appending instead
React attempting to replace view, appending instead

Time:09-27

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)

What am I doing wrong here?

CodePudding user response:

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>
    );
}
  • Related