admin管理员组

文章数量:1402016

If I want to make a web application using reactjs that is not a single page. Should I pile all the react code into a single file and load it on all pages of the application, then use the function that I expose to render the necessary ponents?

Example of an html file

<div id="Clock" data-react="Clock"></div>
<div id="HelloWorld" data-react="HelloWorld"></div>

example of index.js

import React from 'react';
import ReactDOM from 'react-dom';
import Clock from './Clock';
import HelloWorld from './HelloWorld';
import OtherComponent from './OtherComponent';

const APPS = {
    Clock,
    HelloWorld,
    OtherComponent
};

const MyReactRender = react => {

    let ponent = react.getAttribute('data-react');
    let App = APPS[ponent];

    if(App != undefined) {
        ReactDOM.render(<App />, document.getElementById(ponent));
    }
}

document.querySelectorAll('[data-react]').forEach(MyReactRender);

If I want to make a web application using reactjs that is not a single page. Should I pile all the react code into a single file and load it on all pages of the application, then use the function that I expose to render the necessary ponents?

Example of an html file

<div id="Clock" data-react="Clock"></div>
<div id="HelloWorld" data-react="HelloWorld"></div>

example of index.js

import React from 'react';
import ReactDOM from 'react-dom';
import Clock from './Clock';
import HelloWorld from './HelloWorld';
import OtherComponent from './OtherComponent';

const APPS = {
    Clock,
    HelloWorld,
    OtherComponent
};

const MyReactRender = react => {

    let ponent = react.getAttribute('data-react');
    let App = APPS[ponent];

    if(App != undefined) {
        ReactDOM.render(<App />, document.getElementById(ponent));
    }
}

document.querySelectorAll('[data-react]').forEach(MyReactRender);
Share Improve this question edited Sep 1, 2017 at 16:10 Félix Adriyel Gagnon-Grenier 8,89310 gold badges57 silver badges67 bronze badges asked Sep 1, 2017 at 15:31 MrGilbertManMrGilbertMan 831 silver badge7 bronze badges 5
  • I'd just go with if (document.getElementById('Clock')) {/*activate react ponent*/} – Félix Adriyel Gagnon-Grenier Commented Sep 1, 2017 at 15:43
  • Thanks for the input. But, would it be correct to use this method, given that the application can grow a lot? – MrGilbertMan Commented Sep 1, 2017 at 15:49
  • No, it's definitely not a remended practice, but the only real downsides are the size of the bundle and an ever increasing number of ifs. A better way could be to use webpack to bundle different part of the applications, and only load them in each different page – Félix Adriyel Gagnon-Grenier Commented Sep 1, 2017 at 15:51
  • Would this generate a js for each page? – MrGilbertMan Commented Sep 1, 2017 at 16:07
  • yes, it would, see my answer – Félix Adriyel Gagnon-Grenier Commented Sep 1, 2017 at 16:09
Add a ment  | 

2 Answers 2

Reset to default 5

I'd see two ways, of increasing quality and difficulty. In both cases, you use good old anchors elements to redirect the page to a url, to which different templates correspond.

  • Manually check for the existence of divs id's

In this case, each template includes the same javascript bundle that contains everything in the app and a single element with an id corresponding to the specific ponent. The idea is to check wether or not an element is present in the page, then activate its corresponding react ponent if it is.

if (document.getElementById('ponent-root')) {
  ReactDOM.render(<Component />, document.getElementById('ponent-root'));
}

On the up side, it's quite easily implemented. On the down side, the bundle will always get bigger and bigger, and the list of ifs grows each time you add a new "page".

  • Separate your modules in actual bundles

Different bundle managers exist, but I'd remend using Webpack to create multiple bundles that contain only specific part of your application. Then, each template contains only the corresponding div element, as well as that specific bundle.


<head><script src="/js/clock.js"></head>
<body><div id="root-clock"></div></body>

<head><script src="/js/otherComponent.js"></head>
<body><div id="root-other-ponent"></div></body>

How to package multiple bundles with webpack is out of the scope of this answer, but look here.

I've tried making a react application without a router. I used ternary operators to switch from ponent to ponent.

// App Component
class App extends Component {
  constructor(props) {
    super(props)

   this.state = {
      inClockComponent: true,
      inHelloWorldComponent: false,
      inOtherComponent: false
   }

  }


 render() {
    const {inClockComponent, inHelloWorldComponent, inOtherComponent} = this.state
    return (
      <div>
      {

      inClockComponent 
        ? <Clock> : inHelloWorldComponent 
          ? <HelloWorld> : inOtherComponent ? <OtherComponent> : 
              <div>No Component Here</div>

      } 
     </div>
  }

You could pass a function from the App ponent that would change the display state to each child ponent of App

Example

// in App Component
 showHelloWorldComponent() {
     this.setState({
        inClockComponent: false,
        inHelloWorldComponent: true,
        inOtherComponent: false
     )}
 }

You insert that function onto a button that would navigate to a different ponent

Example

// in Clock Component

render() {
  return (
    <div>
      <h2>Time is 5:15 P.M.</h2>
      <button onClick={this.props.showHelloWorldComponent}>
         Go To Hello World
      </button>
  )
}

It's a messy solution, and I wouldn't suggest using it in a big application, but I hope this answers your question!

本文标签: javascriptUse react without a router componentStack Overflow