简体   繁体   English

使用React Router进行简单导航[错了]

[英]Simple navigation with react router [gone wrong]

I started working on my engineering thesis and decided to write it as SPA in React that communicates with REST API on a ASP.NET Core backend. 我开始研究我的工程论文,并决定在React中将其编写为SPA,并与ASP.NET Core后端上的REST API进行通信。 So far I have done a couple of apps using ASP.NET MVC and Winforms, but I wanted to broaden my knowledge and learn some new technologies. 到目前为止,我已经使用ASP.NET MVC和Winforms完成了一些应用程序,但是我想扩展我的知识并学习一些新技术。 Therefore I started learning React recently and in the beginning I was trying to create really simple SPA in it. 因此,我最近开始学习React,一开始我试图在其中创建非常简单的SPA。

Here is the problem: Let's suppose that we have an app with universities' data. 这是问题所在:假设我们有一个包含大学数据的应用程序。 That is: Universities, their departments, departments' subjects, subjects' lecturers, etc. 即:大学,其系,系的学科,学科的讲师等。

I'd like to have a simple navigation through the above structure - on the main page display every university that I have in a database, then I'd like to be able to click on a university and get it's departments, then on departments list click on one department and get for example subjects from that department, and so on, you get the idea.. 我想对上述结构进行简单的导航-在主页上显示我在数据库中拥有的每所大学,然后我希望能够单击大学并获取其系,然后在系列表中单击一个部门,然后从该部门获取例如主题,依此类推,您就知道了。

My backend with necessary endpoints is running on localhost. 我的具有必要端点的后端正在localhost上运行。 The problem is when and where to fetch the data in frontend, how to pass id's between components, how to do a structure for such an application, etc. 问题在于何时何地在前端获取数据,如何在组件之间传递id,如何为此类应用程序构造结构等。

I've spent 3 days doing it and tried everything but unfortunately with no effect, and now I have such a mess in my head that I consider going back to good old ASP.NET MVC.. But I'm sure there must be something I'm missing and don't understand because I don't believe it's not possible.. I think I could also have many habits from MVC that might affect my understanding of web apis and pure frontent apps. 我花了3天的时间进行尝试,但不幸的是没有任何效果,但是现在我的脑海一片混乱,我考虑重新使用旧的ASP.NET MVC。。但是我敢肯定,肯定有一些东西我很想念我,因为我不相信这是不可能的。.我想我也可能有很多MVC习惯,可能会影响我对Web api和纯前端应用程序的理解。

I've read official documentation, watched tutorials, stackoverflowed, tried my own ideas, repeated every step 5 times. 我已经阅读了官方文档,观看了教程,stackoverflowed,尝试了自己的想法,每步重复5次。 Simple routing and overall react workflow are not a problem for me, the problem is that specific scenario. 简单的路由和整体反应工作流程对我来说不是问题,问题在于特定的情况。

Could anyone provide me some information or clues how to deal with such a design in React (ideally with examples)? 谁能为我提供一些信息或线索,以了解如何在React中处理此类设计(理想情况下带有示例)?


EDIT 编辑

Ok, so I'm sharing the design I came up with today. 好的,我现在分享我今天想出的设计。 This works as expected but there's no possibility to go to a specific route manually, by entering it in browser's searchbox - the only way is to go down through the whole "university path" 这可以按预期工作,但是无法通过在浏览器的搜索框中输入特定的路线来手动进行选择-唯一的方法是沿着整个“大学路径”浏览

App.js 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 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 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 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

And finally - Lessons.js 最后-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

As all this is very repetitive while we start going down deeper in the university path, I think it would be nice to flatten those lists in one List component (with maybe some specific properties in case I want to display some more things) and only pass fetched elements to it. 由于所有这些都是非常重复的,当我们开始更深入地研究大学时,我认为最好将这些列表放到一个List组件中(如果要显示更多内容,可以包含一些特定属性),并且只通过获取元素。 Almost whole app uses that "list like" gui so it could be useful. 几乎整个应用程序都使用该“类似于列表”的gui,因此它可能很有用。 That's the case I will be working on now. 我现在就是这种情况。

Now when you see what design I had in my mind feel free to share your thoughts about it. 现在,当您看到什么设计时,我便可以随意分享您的想法。 Maybe I should have it done in some other, better way? 也许我应该以其他更好的方式完成它?


EDIT 2 编辑2

Updated code, added breadcrumbs! 更新了代码,添加了面包屑! Cool, but there's a big problem that I mentioned earlier - I can't get directly to specific route, therefore I can't go back from lessons to departments... So the whole Router thing is useless, especially when I want to share links to specific routes (in the future). 很酷,但是我前面提到了一个大问题-我无法直接转到特定的路线,因此无法从课程回到部门...所以整个Router事情都是无用的,尤其是当我想共享时链接到特定的路线(将来)。 Anyway here is an updated code. 无论如何,这里是一个更新的代码。

The problem is when and where to fetch the data in frontend, how to pass id's between components, how to do a structure for such an application, etc. 问题在于何时何地在前端获取数据,如何在组件之间传递id,如何为此类应用程序构造结构等。

Typically, you would use a state container library for this. 通常,您将为此使用状态容器库。 The most commonly used with React is Redux . 最常用于React的是Redux You would store/cache the response data in the store, fire requests using actions and parse the response in reducers. 您将在存储中存储/缓存响应数据,使用操作激发请求并在化简器中解析响应。 You can also use redux-promise middleware to dispatch actions for async calls/requests. 您还可以使用redux-promise中间件为异步调用/请求调度操作。

A good video tutorial that explains this in depth is: https://www.udemy.com/react-redux/ 一个很好的视频教程可以对此进行深入解释, 网址为: https : //www.udemy.com/react-redux/

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM