Я новичок в ReactJs, и у меня есть компонент ProjectsList, который включает в себя таблицу html. Один из его столбцов - это ссылка, при нажатии на которую она должна перейти на другую страницу, отображающую компонент ProjectInfo.

Но происходит то, что компонент отображается на той же странице компонента ProjectsList в конце таблицы. Компонент ProjectsList отображается при нажатии на ссылку Show Projects в компоненте Projects.

< Сильный > Projects.component.jsx

import React, { Component } from "react";
import { Link, Route, Switch } from "react-router-dom";
import NewProject from "../NewProject/NewProject.component";
import ProjectsList from "../ProjectsList/ProjectsList.component";
import "./Projects.css";

export default class Projects extends Component {
  render() {
    return (
      <div className="projects-dashboard">
        <nav className="nav-up">
          <ul>
            <li>
              <Link to={"/dashboard/projects/add"}>add project</Link>
            </li>

            <li>
              <Link to={"/dashboard/projects/list"}>show projects</Link>
            </li>
          </ul>
        </nav>
        <main>
          <Route path={"/dashboard/projects/add"} component={NewProject} />
          <Route path={"/dashboard/projects/list"} component={ProjectsList} />
        </main>
      </div>
    );
  }
}

< Сильный > ProjectsList.component.jsx

import React, { Component } from "react";
import axios from "axios";
import { Route, Link } from "react-router-dom";
import "./ProjectsList.css";
import ProjectInfo from "../ProjectInfo/ProjectInfo.component";

export default class ProjectsList extends Component {
  constructor(props) {
    super(props);
    this.state = {
      allProject: []
    }
  }

  componentWillMount() {
    this.fetchAllProjects();
  }

  componentDidMount() {
    document.body.style.overflowY = "auto";
  }

  fetchAllProjects = () => {
    axios.get("/api/projects").then(res => {
      this.setState({ allProject: res.data }, () => { console.log(this.state.allProject); });
    });
  };

  render() {
    const projects = this.state.allProject.map(project => {
      return (
        <tr>
          <td>{project.id}</td>
          <td>{project.title}</td>
          <td>{project.organization_name}</td>
          <td className="project-options">
            <Link to={`/dashboard/projects/list/${project.id}`}>
              <i className="far fa-eye" /> show
            </Link>
          </td>
        </tr>
      );
    });

    return (
      <div>
        <table class="projects-list-table">
          <thead>
            <tr>
              <th>
                <h1>Project ID</h1>
              </th>
              <th>
                <h1>Project Name</h1>
              </th>
              <th>
                <h1>Organization Name</h1>
              </th>
              <th>
                <h1>Options</h1>
              </th>
            </tr>
          </thead>
          <tbody>{projects}</tbody>
        </table>
        <main>
          <Route path={"/dashboard/projects/list/:id"} component={ProjectInfo} />
        </main>
      </div>
    );
  }
}

< Сильный > ProjectInfo.component.jsx

import React, { Component } from 'react';
import "./ProjectInfo.css";

export default class ProjectInfo extends Component {
    render() {
        return (
            <div>
                <h1>Project Info Component</h1>
            </div>
        )
    }
}
1
Shatha 23 Окт 2018 в 11:48

2 ответа

Лучший ответ

Маршрутизатор React включает эти компоненты в указанный раздел, где находится тег Route. Например:

<section>
  <h1>Hello</h1>
  <Route path={"/random/path"} component={MyComponent} />
</section>

Вернется

<section>
  <h1>Hello</h1>
  <MyComponent />
</section>

Чтобы обойти это, вам нужно добавить его к тому же уровню маршрутизации, что и ваш маршрут PrjectList.

Так что измени это

<main>
  <Route path={"/dashboard/projects/add"} component={NewProject} />
  <Route path={"/dashboard/projects/list"} component={ProjectsList} />
</main>

Кому

<main>
  <Route path={"/dashboard/projects/add"} component={NewProject} />
  <Route exact path={"/dashboard/projects/list"} component={ProjectsList} />
  <Route exact path={"/dashboard/projects/list/:id"} component={ProjectInfo} />
</main>

< Сильный > ИЗМЕНИТЬ

На последнем маршруте не должно быть точного тега.

<main>
  <Route path={"/dashboard/projects/add"} component={NewProject} />
  <Route exact path={"/dashboard/projects/list"} component={ProjectsList} />
  <Route path={"/dashboard/projects/list/:id"} component={ProjectInfo} />
</main>
1
DevDwarf 23 Окт 2018 в 09:06

Если вы хотите визуализировать компонент исключительно, это означает, что вы хотите визуализировать только один конкретный компонент (в вашем случае это ProjectInfo), когда вы нажимаете ссылку в таблице, и в этом случае вы не хотите для рендеринга компонента Projects вам необходимо использовать Switch в маршрутизаторе.

Из официальных документов

< Сильный > <Switch>

Отображает первый дочерний элемент <Route> или <Redirect>, который совпадает с местоположением.

Чем это отличается от простого использования набора <Route>?

<Switch> уникален тем, что отображает исключительно маршрут. В напротив, каждый <Route>, который соответствует местоположению, отображает включительно.

Рассмотрим этот код:

<Route path="/about" component={About}/> 
<Route path="/:user" component={User}/>
<Route component={NoMatch}/>

Если URL равен / about, то <About>, <User> и <NoMatch> будут рендеринг, потому что все они соответствуют пути. Это сделано специально, что позволяет нам создавать <Route> в наших приложениях разными способами, например боковыми панелями и панировочные сухари, вкладки начальной загрузки и т. д.

Итак, измените компонент Projects на что-то вроде этого (вы уже импортируете Switch, поэтому нет необходимости импортировать его снова):

<main>
  <Switch>
    <Route exact path={"/dashboard/projects/add"} component={NewProject} />
    <Route exact path={"/dashboard/projects/list"} component={ProjectsList} />
  </Switch>
</main>
1
c-chavez 24 Окт 2018 в 11:38
52944856