【问题标题】:Simple navigation with react router [gone wrong]使用反应路由器进行简单导航[出错]
【发布时间】:2018-10-17 20:49:50
【问题描述】:

我开始撰写我的工程论文,并决定将其编写为 React 中的 SPA,它与 ASP.NET Core 后端上的 REST API 进行通信。到目前为止,我已经使用 ASP.NET MVC 和 Winforms 完成了几个应用程序,但我想拓宽我的知识并学习一些新技术。因此我最近开始学习 React,一开始我试图在其中创建非常简单的 SPA。

问题来了: 假设我们有一个包含大学数据的应用程序。即:大学及其系、系的学科、学科的讲师等。

我想通过上述结构进行简单导航 - 在主页上显示我在数据库中拥有的每所大学,然后我希望能够点击一所大学并获取它的部门,然后在部门列表上单击一个部门并从该部门获取例如主题,依此类推,您就明白了..

带有必要端点的后端正在本地主机上运行。问题是在前端何时何地获取数据,如何在组件之间传递 id,如何为这样的应用程序做一个结构,等等。

我已经花了 3 天的时间尝试了所有方法,但不幸的是没有任何效果,现在我脑子里一片混乱,以至于我考虑回到好的旧 ASP.NET MVC.. 但我确定在那里一定是我想念的东西,不明白,因为我不相信这是不可能的.. 我想我也可能有许多来自 MVC 的习惯,这可能会影响我对 Web api 和纯前端应用程序的理解。

我已经阅读了官方文档,观看了教程,stackoverflow,尝试了自己的想法,每一步都重复了 5 次。简单的路由和整体反应工作流程对我来说不是问题,问题在于特定场景。

谁能给我一些信息或线索如何在 React 中处理这样的设计(最好有例子)?


编辑

好的,所以我将分享我今天想出的设计。这可以按预期工作,但不可能通过在浏览器的搜索框中输入手动进入特定路线 - 唯一的方法是通过整个“大学路径”

App.js

const App = () =>
  <BrowserRouter>
    <>
      <NavBar />

      <div className="row home-container">
        <div className="col s12 m8 l9 home-part">
          <div className="data-container">
            <Route path="/" component={MainContainer} />
          </div>
        </div>
        <Sidebar />
      </div>
    </>
</BrowserRouter>

export default App

MainContainer.js

const defaultBreadcrumb = { title: "Uczelnie", path: "/universities" };

class MainContainer extends React.Component {
  state = {
    elements: [],
    breadcrumbs: [
      defaultBreadcrumb
    ]
  }

  componentDidMount() {
    fetch(`https://localhost:44349/api/v1/universities`)
      .then(res => res.json())
      .then(json => this.setState({elements: json}));
  }

  componentWillReceiveProps(nextProps){
    if(nextProps){
      var newBreadcrumbs = nextProps.location.breadcrumbs ? nextProps.location.breadcrumbs : [defaultBreadcrumb];

      this.setState({
        breadcrumbs: newBreadcrumbs
      });
    }
  }

  render() {
    return (
      <>
        <nav className="colornav">
          <div className="nav-wrapper path-header-wrapper">
            <div className="col s12 subsite-title">
              {this.state.breadcrumbs.map((b, key) => (
                <NavLink key={key} to={b.path} className="breadcrumb">{b.title}</NavLink>
              ))}
            </div>
          </div>
        </nav>

        <div className="home-content">
          <ul className="collection">
            <Route 
              exact 
              path="/universities" 
              render={() => {return <Universities elements={this.state.elements} />}} 
            />
            <Route 
              exact 
              path="/universities/:id"
              render={() => { return <Departments {...this.props} />}} 
            />
            <Route 
              exact 
              path="/universities/:id/Lessons"
              render={() => { return <Lessons {...this.props} />}} 
            />
          </ul>
        </div>
      </>
    );
  }
}

export default MainContainer

Universities.js

const Universities = ({elements}) => 
  <>
    {elements.map((u) => 
      <NavLink 
        key={u.name} 
        to={{
          pathname: `/universities/${u.name}`, 
          univId: u.universityId,
          univName: u.name,
          breadcrumbs: [
            {title: "Uczelnie", path: `/universities`}, 
            {title: u.name, path: `/universities/${u.universityId}`}
          ]
        }} 
        className="collection-item path-list-item">

        <div>{u.name}
          <li className="secondary-content">
            <i className="material-icons">send</i>
          </li>
        </div>
      </NavLink>
    )}
  </>

export default Universities

Departments.js

class Departments extends React.Component {
  state = {
    elements: []
  }

  componentDidMount() {
    fetch(`https://localhost:44349/api/v1/departmentsofuniversity/${this.props.location.univId}`)
      .then(res => res.json())
      .then(json => this.setState({elements: json}));
  }

  render() {
    return (
      <>
        {this.state.elements.map((d) => 
          <NavLink 
            key={d.name} 
            to={{
              pathname: `/universities/${d.name}/lessons`, 
              deptId: d.departmentId,
              deptName: d.name,
              breadcrumbs: [
                {title: "Uczelnie", path: `/universities`}, 
                {title: this.props.location.univName, path: `/universities/${this.props.location.univId}`}, 
                {title: d.name, path: `/universities/${this.props.location.univId}/lessons`}
              ]
            }} 
            className="collection-item path-list-item">

            <div>{d.name}
              <li className="secondary-content">
                <i className="material-icons">send</i>
              </li>
            </div>
          </NavLink>
        )}
      </>
    );
  }
}

export default Departments

最后——Lessons.js

class Lessons extends React.Component {
  state = {
    elements: []
  }

  componentDidMount() {
    fetch(`https://localhost:44349/api/v1/lessonsfromdepartment/${this.props.location.deptId}`)
      .then(res => res.json())
      .then(json => this.setState({elements: json}));
  }

  render() {
    return (
      <>
        {this.state.elements.map((l, key) => 
          <NavLink 
            key={key} 
            to={{
              pathname: `/universities/${l.name}/Lessons/${l.name}`, 
              deptId: l.departmentId,
              breadcrumbs: [
                {title: "Uczelnie", path: `/universities`}, 
                {title: this.props.location.univName, path: `/universities/${this.props.location.univId}`}, 
                {title: this.props.location.deptName, path: `/universities/${this.props.location.deptName}/lessons`},
                {title: l.name, path: `/universities/${this.props.location.deptId}/lessons/${l.name}`}
              ]
            }} 
            className="collection-item path-list-item">

            <div>{l.name}
              <li className="secondary-content">
                <i className="material-icons">send</i>
              </li>
            </div>
          </NavLink>
        )}
      </>
    );
  }
}

export default Lessons

当我们开始在大学道路上走得更深时,所有这些都是非常重复的,我认为将这些列表展平在一个 List 组件中会很好(如果我想显示更多的东西,可能会有一些特定的属性)并且只将获取的元素传递给它。几乎整个应用程序都使用“类似列表”的 gui,因此它可能很有用。这就是我现在要处理的情况。

现在,当您看到我心中的设计时,请随时分享您的想法。也许我应该以其他更好的方式完成它?


编辑 2

更新代码,添加面包屑!很酷,但是我之前提到了一个大问题 - 我无法直接到达特定路线,因此我无法从课程回到部门......所以整个路由器的东西都没用,尤其是当我想分享时指向特定路线的链接(将来)。无论如何,这是一个更新的代码。

【问题讨论】:

  • 我强烈建议您提供您在 React.js 中尝试过的代码示例,以帮助其他人轻松准确地指出您的实施中出了什么问题。

标签: javascript reactjs react-router react-router-v4 react-router-dom


【解决方案1】:

问题是在前端何时何地获取数据,如何获取 在组件之间传递 id,如何为这样的 应用等

通常,您会为此使用状态容器库。 React 最常用的是Redux。您将在存储中存储/缓存响应数据,使用操作触发请求并在减速器中解析响应。您还可以使用 redux-promise 中间件来调度异步调用/请求的操作。

一个很好的视频教程可以深入解释这一点:https://www.udemy.com/react-redux/

【讨论】:

  • 我认为对于这样一个微不足道的设计来说,整个 Redux 的事情都太过分了,但根据你的建议,我检查了它,似乎这可能是我正在寻找的解决方案。谢谢你。如果有人想出一个纯粹的 React 解决方案,我会再把这个问题留一天。
猜你喜欢
  • 1970-01-01
  • 2016-04-10
  • 2020-12-31
  • 1970-01-01
  • 2017-08-05
  • 2020-10-27
  • 2021-03-29
  • 2016-04-24
相关资源
最近更新 更多