在多页面应用中使用React

Jos*_*llo 111 javascript node.js reactjs

我一直在玩React,到目前为止我真的很喜欢它.我正在使用NodeJS构建一个应用程序,并希望将React用于整个应用程序中的一些交互式组件.我不想让它成为单页应用程序.

我还没有在网上找到任何回答以下问题的内容:

如何在多页应用程序中拆分或捆绑我的React组件?

目前我的所有组件都在一个文件中,即使我可能永远不会在应用程序的某些部分加载它们.

到目前为止,我正在尝试使用条件语句通过搜索React将呈现的容器的ID来呈现组件.我不是100%确定React的最佳实践.它看起来像这样.

if(document.getElementById('a-compenent-in-page-1')) {
    React.render(
        <AnimalBox url="/api/birds" />,
        document.getElementById('a-compenent-in-page-1')
    );
}

if(document.getElementById('a-compenent-in-page-2')) {
    React.render(
        <AnimalBox url="/api/cats" />,
        document.getElementById('a-compenent-in-page-2')
    );
}

if(document.getElementById('a-compenent-in-page-3')) {
    React.render(
        <AnimalSearchBox url="/api/search/:term" />,
        document.getElementById('a-compenent-in-page-3')
    );
}
Run Code Online (Sandbox Code Playgroud)

我仍在阅读文档,但还没有找到我需要的多页面应用程序.

提前致谢.

web*_*deb 74

目前,我正在做类似的事情.

该应用程序不是一个完整的React应用程序,我使用React进行动态Stuff,比如CommentBox,它是autark.并且可以包含在任何具有特殊参数的点...

但是,我的所有子应用程序都已加载并包含在一个文件中all.js,因此浏览器可以跨页面缓存它.

当我需要将一个App包含到SSR模板中时,我只需要包含一个带有"__react-root"类和特殊ID的DIV(要呈现的React App的名称)

逻辑非常简单:

import CommentBox from './apps/CommentBox';
import OtherApp from './apps/OtherApp';

const APPS = {
  CommentBox,
  OtherApp
};

function renderAppInElement(el) {
  var App = APPS[el.id];
  if (!App) return;

  // get props from elements data attribute, like the post_id
  const props = Object.assign({}, el.dataset);

  ReactDOM.render(<App {...props} />, el);
}

document
  .querySelectorAll('.__react-root')
  .forEach(renderAppInElement)
Run Code Online (Sandbox Code Playgroud)
<div>Some Article</div>
<div id="CommentBox" data-post_id="10" class="__react-root"></div>

<script src="/all.js"></script>
Run Code Online (Sandbox Code Playgroud)

编辑

由于webpack完全支持代码分割和LazyLoading,我认为包含一个示例是有意义的,您不需要在一个捆绑包中加载所有应用程序,而是将它们拆分并按需加载.

import React from 'react';
import ReactDOM from 'react-dom';

const apps = {
  'One': () => import('./One'),
  'Two': () => import('./Two'),
}

const renderAppInElement = (el) => {
  if (apps[el.id])  {
    apps[el.id]().then((App) => {
      ReactDOM.render(<App {...el.dataset} />, el);
    });
  }
}
Run Code Online (Sandbox Code Playgroud)


Coc*_*ico 50

您可以在webpack.config.js文件中为应用程序提供多个入口点:

var config = {
  entry: {
    home: path.resolve(__dirname, './src/main'),
    page1: path.resolve(__dirname, './src/page1'),
    page2: path.resolve(__dirname, './src/page2'),
    vendors: ['react']
  },
 output: {
    path: path.join(__dirname, 'js'),
    filename: '[name].bundle.js',
    chunkFilename: '[id].chunk.js'
  },
}
Run Code Online (Sandbox Code Playgroud)

然后你可以在你的src文件夹中有三个不同的html文件及其各自的js文件(例如page1):

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>Page 1</title>
</head>
<body>
  <div id="app"></div>
  <script src="./vendors.js"></script>
  <script src="./page1.bundle.js"></script>
</body>
</html>
Run Code Online (Sandbox Code Playgroud)

JavaScript文件:

import React from 'react'
import ReactDom from 'react-dom'
import App from './components/App'
import ComponentA from './components/ReactComponentA'
ReactDom.render(<div>
                  <App title='page1' />
                  <ReactComponentA/>
                 </div>, document.getElementById('app'))
Run Code Online (Sandbox Code Playgroud)

然后可以为每个页面加载不同的React组件.


Sco*_*ott 32

编辑:11/01/2015

我正在从头开始构建一个应用程序,我正在学习,但我认为你在寻找的是React-Router.React-Router将您的组件映射到特定的URL.例如:

render((
    <Router>
        <Route path="/" component={App}>
            <Route path="api/animals" component={Animals}>
               <Route path="birds" component={Birds}/>
               <Route path="cats" component={Cats}/>
            </Route>
        </Route>
        <Route path="api/search:term" component={AnimalSearchBox}>
    </Router>
), document.body)
Run Code Online (Sandbox Code Playgroud)

在搜索案例中,'term'可以作为AnimalSearchBox中的属性访问:

componentDidMount() {
    // from the path `/api/search/:term`
    const term = this.props.params.term
}
Run Code Online (Sandbox Code Playgroud)

试试看. 教程是我对这个和其他相关主题的理解使我超越的教程.

原始答案如下:

我在这里寻找同样的答案.看看这篇文章是否能激发你的灵感.如果您的应用程序与我的应用程序类似,那么它的区域变化很小,仅在主体中有所不同.您可以创建一个小部件,它负责根据应用程序的状态呈现不同的小部件.使用磁通体系结构,您可以调度导航操作,更改您的主体窗口小部件切换的状态,从而有效地更新页面主体.

这就是我现在正在尝试的方法.

  • 如果URL路径是由我的后端代码(在这种情况下是nodejs)创建的,该怎么办?`Router`的工作方式与单页应用中的工作方式相同吗? (8认同)

jen*_*nas 11

你在使用CMS吗?他们倾向于喜欢改变可能会破坏你的申请的网址.

另一种方法是使用像React Habitat这样的东西.

有了它,您可以注册组件,它们会自动暴露在dom中.

注册组件:

container.register('AnimalBox', AnimalBox);
container.register('AnimalSearchBox', AnimalSearchBox);
Run Code Online (Sandbox Code Playgroud)

然后他们就像这样在你的dom中可用:

<div data-component="AnimalBox"></div>

<div data-component="AnimalSearchBox"></div>
Run Code Online (Sandbox Code Playgroud)

以上内容将自动替换为您的反应组件.

然后,您也可以自动将属性(或道具)传递给组件:

<div data-component="AnimalBox" data-prop-size="small"></div>
Run Code Online (Sandbox Code Playgroud)

这将size作为您的组件的支柱公开.还有其他选项可以传递其他类型,如json,array,int,float等.