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