Динамическая маршрутизация на React-Router - PullRequest
0 голосов
/ 13 января 2019

Я пытаюсь сопоставить wordpress rest api страниц с react-router маршрутами динамически.

index.js file

import React from 'react'
import { render } from 'react-dom'
import { BrowserRouter as Router, Route, Switch } from 'react-router-dom'
import './index.css'

import Home from './components/Home'
import Project from './components/Project'
import Page from './components/Page'
import Header from './components/Header'
import NotFound from './components/NotFound'
import Projects from './components/Projects'

const siteURL = 'http://wp.test'

const getPages = () => {
  return new Promise((resolve, reject) => {
    const endpoint = `${siteURL}/wp-json/better-rest-endpoints/v1/pages?content=false&acf=false&media=false&per_page=99`

    fetch(endpoint)
      .then(response => response.json())
      .then(pages => {
        resolve(pages)
      })
      .catch(error => console.error(error))
  })
}

const identifyComponent = template => {
  const components = {
    'page-projects': Projects
  }
  if (template !== 'default' && template) {
    return components[template]
  } else {
    return Page
  }
}

class AppInit {
  // build the app and routes with page response
  buildApp () {
    async function buildRoutes () {
      let pageList = await getPages()
      render(
        <div>
          <Router>
            <div>
              <Header />
              <Switch>
                <Route
                  path='/'
                  render={props => <Home siteURL={siteURL} {...props} />}
                  exact
                />
                {pageList.map((page, i) => {
                  let Template = identifyComponent(page.template)
                  let pageID = page.id
                  let parent = page.parent
                  return (
                    <Route
                      key={pageID}
                      path={`${parent ? '/' + parent : ''}/${page.slug}`} // /parent/page.slug   **    /page.slug
                      render={props => (
                        <Template
                          pageID={pageID}
                          siteURL={siteURL}
                          {...props}
                        />
                      )}
                      // component={Template}
                      exact
                    />
                  )
                })}
                <Route component={NotFound} />
              </Switch>
            </div>
          </Router>
        </div>,
        document.getElementById('root')
      )
    }
    buildRoutes()
  }
  /*
   * Run the App
   */
  run () {
    this.buildApp()
  }
}
new AppInit().run()

А вот и результат запроса getPages

[
  {
    "id": 12,
    "title": "Project 2",
    "slug": "project-2",
    "permalink": "http://wp.test/projects/project-2/",
    "template": "page-projects",
    "parent": "projects",
    "yoast": false
  },
  {
    "id": 10,
    "title": "Project 1",
    "slug": "project-1",
    "permalink": "http://wp.test/projects/project-1/",
    "template": "page-projects",
    "parent": "projects",
    "yoast": false
  },
  {
    "id": 8,
    "title": "Projects",
    "slug": "projects",
    "permalink": "http://wp.test/projects/",
    "template": "page",
    "parent": false,
    "yoast": false
  },
  {
    "id": 2,
    "title": "Sample Page",
    "slug": "sample-page",
    "permalink": "http://wp.test/sample-page/",
    "template": "page",
    "parent": false,
    "yoast": false
  }
]

Если я пойду по маршруту /projects/project-1, это сработает. Но если я иду по родительским маршрутам, таким как /projects или /sample-page, я получаю сообщение об ошибке.

ошибка

Element type is invalid: expected a string (for built-in components) or a class/function (for composite components) but got: undefined. You likely forgot to export your component from the file it's defined in, or you might have mixed up default and named imports.

Check the render method of `Route`.

Чего мне не хватает? Почему дочерние узлы работают, а другие нет?

...