Я пытаюсь создать приложение изоморфного реагирования.Я использую экспресс в качестве бэк-энда.У меня есть статический маршрутизатор с компонентом приложения в нем.Я ловлю любой запрос и использую renderToString следующим образом:
(приведенный ниже код неполон и может иметь синтаксические ошибки - не запускался через IDE)
server.jsx:
app.get("/*", (req, res) => {
const itemIDs =
['myFirstItemID', 'mySecondItemID', 'myThirdItemID'] // fetched from DB
const renderedApp =
ReactDOM.renderToString(<StaticRouter> <App itemIDs=itemIDs /> </StaticRouter>);
res.render("index", { renderedData: renderedApp });
res.end();
}
App.jsx - только метод визуализации
render() {
const renderedRoutes = this.props.itemIDs.map(itemID => (<Route path={itemID} render={() => <Item ItemID={itemID}/>} />)
);
return (
<Switch>
{renderedRoutes}
<Route component={ItemsContainer itemIDs=itemIDs} />
</Switch>
)
}
ItemsContainer.jsx - только метод визуализации
render() {
const ItemSummaries = this.props.itemIDs.map(itemId => <ItemPreview itemId={itemId}/>)
return (
<div>
{ItemSummaries}
</div>
)
ItemPreview.jsx - только метод визуализации
render() {
return (
<div>
<Link to={"/" + this.props.itemId}>
<h2>an item</h2>
</Link>
</div>
)
Item.jsx - componendDidMount и рендер
componentDidMount() {
axios.get("/api/items?itemID=" + this.props.itemID)
.then((data) => this.state.itemData = data);
render() {
return (
<div>
//use itemData here
</Link>
</div>
)
Client.jsx - обслуживается клиенту (использует тот же компонент App.jsx)
const MyRoutedApp = () =>
(<BrowserRouter>
<App />
</BrowserRouter>);
ReactDOM.hydrate(<MyRoutedApp/>, document.getElementById('root'));
Я чувствую, что что-то очень неправильно вмой подход, но я не уверен, что.У меня есть следующие проблемы:
- ItemIDs используются только на сервере для генерации маршрутов.Как только приложение становится доступным на клиенте, у меня больше нет маршрутов, поэтому BrowserRouter не работает.Я могу получить маршруты, используя ajax, но это приводит к тому, что первоначальный рендеринг происходит до того, как у меня есть необходимые данные, что приводит к тому, что всегда отображается ItemsContainer (маршрут по умолчанию) для нескольких кадров независимо от того, по какому URL я нахожусь.
- Какие у меня есть варианты, чтобы сделать renderToString компонентом, который полагается на ajax в componentDidMount для определения его содержимого render () (Item.jsx)?
- И последнее, но не менее важное - действительно ли это хороший подход??