【发布时间】:2023-04-01 04:30:01
【问题描述】:
我正在尝试构建一个同构反应应用程序。我使用 express 作为后端。我有一个带有 App 组件的静态路由器。我捕捉到任何请求并像这样使用 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'));
我觉得我的方法有些问题,但我不确定是什么。 我遇到的问题是:
- ItemID 仅在服务器内用于生成路由。一旦应用程序在客户端可用,我就不再有路由,所以 BrowserRouter 不起作用。我可以使用 ajax 获取路由,但这会导致在我获得所需数据之前进行初始渲染,这导致无论我在哪个 URL 上总是看到几帧的 ItemsContainer(默认路由)。李>
- 要 renderToString 一个依赖于 componentDidMount 中的 ajax 来决定其 render() 内容 (Item.jsx) 的组件,我有哪些选择?
- 最后但同样重要的是 - 这真的是一个好方法吗?
【问题讨论】:
标签: javascript reactjs react-router-v4 isomorphic-javascript