【问题标题】:(Isomorphic) Back-end rendering of routes and ajax-based react components(同构)路由和基于ajax的react组件的后端渲染
【发布时间】: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


    【解决方案1】:

    因此,我发现解决第一个问题的一种方法是在初始索引页面响应中(在 &lt;script&gt; 标记内)呈现路由,然后让 App 构造函数根据呈现的位置处理路由:

    • 如果由服务器渲染 - 获取传递的道具
    • 如果在浏览器中呈现 - 获取全局对象。

    这是它在代码中的样子:

    索引页面中的某处(EJS 模板):

    //
    <script>const globalRoutes = <%- JSON.stringify(renderedRoutes) %> </script>
    //
    

    “/”请求处理程序:

    var fetchedRoutes; //your routes
    app.get("/*", (req, res) => {
    
        var context = {};
        const routedApp = ReactDOMServer.renderToString(
            React.createElement(
                StaticRouter,
                { location: req.url, context: context },
                React.createElement(App, {routesData: fetchedRoutes})
      )
          );
    
        res.render("index", { renderedData: routedApp, renderedRoutes: fetchedRoutes });
        res.end();
    
    });
    

    App如何处理路由:

    class App extends React.Component {
        constructor(props) {
            super(props);
            this.state = { routesData: this.isBrowser() ? globalRoutes : this.props.routesData }
        }
    

    【讨论】:

      猜你喜欢
      • 2019-11-26
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-05-11
      • 2018-05-29
      • 1970-01-01
      • 2018-05-30
      • 1970-01-01
      相关资源
      最近更新 更多