问题
I am trying to setup micro-frontend architecture for the project. The project contains multiple react
apps. Following is the project structure:
- container
- header (npm package)
- dashboard (npm package)
- app1 (npm package)
- app2 (npm package)
- app3 (npm package)
Here, container works as wrapper for the other apps. Dashboard apps shows links to the other apps such as app1, app2, app3 etc...
Once user logs in header and dashboard app renders on a page. From dashboard user can navigate to other apps.
container
import React, { useState, useEffect } from 'react';
import Header from 'header';
import Dashboard from 'dashboard';
import { api } from '../api';
function storeUser(user) {
if (user) {
localStorage.user = JSON.stringify(user);
} else {
delete localStorage.user;
}
}
function Container() {
const [error, setError] = useState([]);
const [user, setUser] = useState();
const login = async () => {
try {
const user = await api({
endpoint: 'identity/login',
method: 'POST',
json: {
email: 'test@abc.com',
password: '12345'
}
});
setUser(user);
storeUser(user);
} catch (err) {
setError(err.message);
}
};
return (
<div>
<input type="submit" value="Login" onClick={() => login()}></input>
{user ? (
<div>
<Header />
<Dashboard />
</div>
) : (
<span>{error}</span>
)}
</div>
);
}
export default Container;
dashboard
function Dashboard() {
const [data, setData] = useState([]);
useEffect(() => {
const fetchData = async () => {
const response = await getApps();
setData(response);
};
fetchData();
}, []);
return (
<ul>
{data.map(item => (
<li key={item.id}>{item.name}</li>
))}
</ul>
);
}
How can I inform container
that li
in dashboard
app (published as npm package) has been clicked and render clicked component/app using react-router
?
回答1:
Simply pass a prop with a callback to the Dashboard root component and use it as onClick
handler:
Container:
<Dashboard onItemClicked={(itemUrl) => this.props.history.push(itemUrl)} />
Dashboard:
<li key={item.id} onClick={() => this.props.onItemClicked(item.url)}>{item.name}</li>
The container component can then use the history
API to push a different route when this function is called. If container is using react-router
(and withRouter
) it should hook into the routing you have set up. A central file where the route paths (strings) are maintained is helpful with this.
Alternatively, you could pass the entire history
prop to the dashboard.
来源:https://stackoverflow.com/questions/60005400/react-communication-and-routing-between-components-published-as-npm-packages