Javascript (同构)路由和基于ajax的react组件的后端呈现
我正在尝试构建一个同构的react应用程序。我使用express作为后端。我有一个静态路由器,里面有一个应用程序组件。我捕获任何请求并使用renderToString,如下所示: (下面的代码不完整,可能有语法错误-未通过IDE运行) server.jsx:Javascript (同构)路由和基于ajax的react组件的后端呈现,javascript,reactjs,react-router-v4,isomorphic-javascript,Javascript,Reactjs,React Router V4,Isomorphic Javascript,我正在尝试构建一个同构的react应用程序。我使用express作为后端。我有一个静态路由器,里面有一个应用程序组件。我捕获任何请求并使用renderToString,如下所示: (下面的代码不完整,可能有语法错误-未通过IDE运行) server.jsx: app.get("/*", (req, res) => { const itemIDs = ['myFirstItemID', 'mySecondItemID', 'myThirdItemID'] // fetched from
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.get(“/*”,(req,res)=>{
常量项ID=
['myFirstItemID','mySecondItemID','myThirdItemID']//从数据库中获取
const renderapp=
renderToString();
res.render(“索引”{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>
)
}
render() {
const ItemSummaries = this.props.itemIDs.map(itemId => <ItemPreview itemId={itemId}/>)
return (
<div>
{ItemSummaries}
</div>
)
render() {
return (
<div>
<Link to={"/" + this.props.itemId}>
<h2>an item</h2>
</Link>
</div>
)
render(){
const renderedRoutes=this.props.itemIDs.map(itemID=>(}/>)
);
返回(
{renderdRoutes}
)
}
ItemsContainer.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>
)
}
render() {
const ItemSummaries = this.props.itemIDs.map(itemId => <ItemPreview itemId={itemId}/>)
return (
<div>
{ItemSummaries}
</div>
)
render() {
return (
<div>
<Link to={"/" + this.props.itemId}>
<h2>an item</h2>
</Link>
</div>
)
render(){
const itemsumeries=this.props.itemIDs.map(itemId=>)
返回(
{项目摘要}
)
ItemPreview.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>
)
}
render() {
const ItemSummaries = this.props.itemIDs.map(itemId => <ItemPreview itemId={itemId}/>)
return (
<div>
{ItemSummaries}
</div>
)
render() {
return (
<div>
<Link to={"/" + this.props.itemId}>
<h2>an item</h2>
</Link>
</div>
)
render(){
返回(
项目
)
Item.jsx-组件添加和渲染
componentDidMount() {
axios.get("/api/items?itemID=" + this.props.itemID)
.then((data) => this.state.itemData = data);
render() {
return (
<div>
//use itemData here
</Link>
</div>
)
componentDidMount(){
axios.get(“/api/items?itemID=“+this.props.itemID”)
.然后((数据)=>this.state.itemData=data);
render(){
返回(
//在这里使用itemData
)
Client.jsx-提供给客户端(使用相同的App.jsx组件)
constmyroutedapp=()=>
(
);
ReactDOM.hydrate(,document.getElementById('root');
我觉得我的方法有点不对劲,但我不确定是什么。
我遇到的问题是:
- ItemID仅在服务器内用于生成路由。一旦应用程序在客户端可用,我就不再有路由,因此BrowserRouter无法工作。我可以使用ajax获取路由,但这会导致在我获得所需数据之前进行初始渲染,这会导致始终看到ItemsContainer(默认路由)用于几个帧,无论我位于哪个URL
- 对于依赖componentDidMount中的ajax来决定其render()内容(Item.jsx)的组件,我可以选择哪些选项来渲染字符串
- 最后但并非最不重要的一点——这真的是一个好方法吗
标记中),然后让应用程序构造函数根据呈现的位置处理路由:
- 如果由服务器渲染-使用传递的道具
- 如果在浏览器中渲染-获取全局对象
class App extends React.Component {
constructor(props) {
super(props);
this.state = { routesData: this.isBrowser() ? globalRoutes : this.props.routesData }
}
因此,我发现解决第一个问题的一种方法是在初始索引页响应中呈现路由(在
标记中),然后让应用程序构造函数根据呈现的位置处理路由:
- 如果由服务器渲染-使用传递的道具
- 如果在浏览器中渲染-获取全局对象
class App extends React.Component {
constructor(props) {
super(props);
this.state = { routesData: this.isBrowser() ? globalRoutes : this.props.routesData }
}