[javascript] 다중 페이지 앱에서 React 사용

나는 React를 가지고 놀았고 지금까지 정말 좋아합니다. NodeJS로 앱을 구축 중이며 애플리케이션 전체의 일부 대화 형 구성 요소에 React를 사용하고 싶습니다. 단일 페이지 앱으로 만들고 싶지 않습니다.

다음 질문에 대한 답을 웹에서 아직 찾지 못했습니다.

다중 페이지 앱에서 React 컴포넌트를 나누거나 번들링하려면 어떻게해야합니까?

현재 모든 구성 요소는 앱의 일부 섹션에서로드하지 않아도 하나의 파일에 있습니다.

지금까지 조건문을 사용하여 React가 렌더링 할 컨테이너의 ID를 검색하여 구성 요소를 렌더링하려고합니다. React의 모범 사례가 무엇인지 100 % 확신하지 못합니다. 이렇게 생겼습니다.

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')
    );
}

아직 문서를 읽고 있지만 아직 다중 페이지 앱에 필요한 것을 찾지 못했습니다.

미리 감사드립니다.



답변

현재 나는 비슷한 일을하고 있습니다.

이 응용 프로그램은 완전한 React 앱이 아니며, 저는 autark 인 CommentBox와 같은 동적 Stuff에 React를 사용하고 있습니다. 그리고 특별한 매개 변수를 사용하여 모든 지점에 포함될 수 있습니다.

그러나 내 모든 하위 앱이로드되고 단일 파일 all.js에 포함되므로 브라우저에서 페이지간에 캐시 할 수 있습니다.

SSR 템플릿에 앱을 포함해야 할 때 “__react-root”클래스와 특수 ID (렌더링 할 React 앱의 이름)가있는 DIV 만 포함하면됩니다.

논리는 정말 간단합니다.

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)

<div>Some Article</div>
<div id="CommentBox" data-post_id="10" class="__react-root"></div>

<script src="/all.js"></script>

편집하다

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);
    });
  }
}


답변

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'
  },
}

그런 다음 src 폴더에 각각의 js 파일이있는 세 개의 다른 html 파일을 가질 수 있습니다 (페이지 1의 예).

<!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>

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'))

그런 다음 각 단일 페이지에 대해 다른 React 구성 요소를로드 할 수 있습니다.


답변

나는 처음부터 응용 프로그램을 만들고 있고 배우면서 배우고 있지만 찾고있는 것은 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)

검색 사례에서 ‘term’은 AnimalSearchBox의 속성으로 액세스 할 수 있습니다.

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

시도해보십시오. 튜토리얼은 이것과 다른 관련 주제에 대한 나의 이해의 관점에서 저를 맨 위에 올려 놓은 것입니다.


원래 답변은 다음과 같습니다.

나는 여기에서 같은 답을 찾기 위해 길을 찾았습니다. 있는지 확인 게시물을 고무시킨다. 귀하의 응용 프로그램이 내 것과 같은 것이라면 거의 변하지 않고 본체에서만 변하는 영역이 있습니다. 응용 프로그램의 상태에 따라 다른 위젯을 렌더링하는 책임이있는 위젯을 만들 수 있습니다. 플럭스 아키텍처를 사용하면 본문 위젯이 전환되는 상태를 변경하는 탐색 작업을 전달하여 페이지 본문 만 효과적으로 업데이트 할 수 있습니다.

이것이 제가 지금 시도하고있는 접근 방식입니다.


답변

CMS를 사용하고 있습니까? 그들은 당신의 응용 프로그램을 망칠 수있는 URL 변경을 좋아하는 경향이 있습니다.

또 다른 방법은 React Habitat 과 같은 것을 사용하는 것 입니다.

이를 통해 구성 요소를 등록 할 수 있으며 자동으로 dom에 노출됩니다.

구성 요소 등록 :

container.register('AnimalBox', AnimalBox);
container.register('AnimalSearchBox', AnimalSearchBox);

그런 다음 그들은 다음과 같이 당신의 돔에서 사용할 수 있습니다.

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

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

위의 내용은 자동으로 반응 구성 요소로 대체됩니다.

그런 다음 속성 (또는 소품)을 구성 요소에도 자동으로 전달할 수 있습니다.

<div data-component="AnimalBox" data-prop-size="small"></div>

이것은 size컴포넌트에 소품으로 노출 됩니다. json, array ‘s, int, floats 등과 같은 다른 유형을 전달하기위한 추가 옵션 이 있습니다 .


답변

이 질문을 한 지 오래되었지만 도움이되기를 바랍니다.

@Cocomico가 언급했듯이 webpack.config.js 파일에서 애플리케이션에 대한 여러 진입 점을 제공 할 수 있습니다. 정적 페이지에 React 구성 요소를 추가 할 수있는 간단한 Webpack 설정 (다중 진입 점 개념을 기반으로 함)을 찾고 있다면 https://github.com/przemek-nowicki/multi-page 사용을 고려할 수 있습니다. -반응이있는 앱


답변

InertiaJS를 살펴 보시기 바랍니다 : https://inertiajs.com/

Inertia를 사용하면 선택한 서버 측 웹 프레임 워크로 항상 해왔 던 것처럼 앱을 빌드 할 수 있습니다. 라우팅, 컨트롤러, 미들웨어, 인증, 권한 부여, 데이터 가져 오기 등에 프레임 워크의 기존 기능을 사용합니다.

유일한 차이점은 뷰 레이어입니다. 서버 측 렌더링 (예 : Blade 또는 ERB 템플릿)을 사용하는 대신보기는 JavaScript 페이지 구성 요소입니다. 이를 통해 React, Vue 또는 Svelte를 사용하여 전체 프런트 엔드를 구축 할 수 있습니다.


답변