简体   繁体   English

如何正确拆分React应用程序组件

[英]How to proper split React application components

I am learning React by creating an application, but I think I underestimated its complexity. 我正在通过创建一个应用程序来学习React,但是我认为我低估了它的复杂性。 Let me share with you to know if I got it right: 让我与您分享一下我是否理解正确:

The idea is to create a React App to track the subjects I want to study. 这个想法是创建一个React App来跟踪我想学习的学科。 I've created the following structure: 我创建了以下结构:

MainTopic:
-- title: String
-- percentage_completed: Number
-- Topic: Array
---- Subtopic: Array
---- title: String
---- percentage_completed: Number
------ Resources: Array
------ title: String
------ link: String
------ completed: Boolean

The JSON structure should look like this - the documents are tighed up by the _id of his parent: JSON结构应如下所示-文档由其父母的_id修饰:

{
    "title": String,
    "percentage_completed": Number
    "topic":[
    {
        "title":String,
        "percentage_completed":Number
        "subtopic":[
        {
            "title":String
            "percentage_completed": Number
            "resources":[
            {
                "title":String
                "link": String
                "concluded": Boolean
            }
            ]
        }
        ]
    }
    ]
}

Each subject is called MainTopic and it has a lot of topics underneath, like: JavaScript has NodeJS, Data Structures, and Algorithms as topic and Express is a subtopic of Node and so on... 每个主题都称为MainTopic,其下有很多主题,例如:JavaScript具有NodeJS,数据结构和算法作为主题,Express是Node的子主题,依此类推。

I have a NodeJS API serving JSON to get the entire list of documents already stored in the database as well as each specific part of it, MainTopics, Topics from a given MainTopic, etc. etc... here you are the JSON it returns: 我有一个提供JSON的NodeJS API,以获取已存储在数据库中的文档的完整列表,以及该数据库的每个特定部分,MainTopics,给定MainTopic中的Topics等,等等...这里是返回的JSON:

[
    {
        "topics": [
            {
                "subtopics": [
                    {
                        "resources": [
                            {
                                "_id": "5b857b00c346783a24cbdbb5",
                                "subtopic_id": "5b857ad0c346783a24cbdbb4",
                                "title": "Udemy Course",
                                "link": "https://udemy.com/dictionaires-nodejs",
                                "concluded": false,
                                "__v": 0
                            }
                        ],
                        "_id": "5b857ad0c346783a24cbdbb4",
                        "title": "Dictionaries",
                        "percentage_concluded": 0,
                        "topic_id": "5b857a12c346783a24cbdbae",
                        "__v": 0
                    }
                ],
                "_id": "5b857a12c346783a24cbdbae",
                "maintopic_id": "5b8565b90c927b2c47df7d9d",
                "title": "Node.js",
                "percentage_concluded": 0,
                "__v": 0
            },
            {
                "subtopics": [
                    {
                        "resources": [],
                        "_id": "5b857ab8c346783a24cbdbb3",
                        "title": "Lists",
                        "percentage_concluded": 0,
                        "topic_id": "5b857a1ac346783a24cbdbaf",
                        "__v": 0
                    }
                ],
                "_id": "5b857a1ac346783a24cbdbaf",
                "maintopic_id": "5b8565b90c927b2c47df7d9d",
                "title": "Java",
                "percentage_concluded": 0,
                "__v": 0
            },
            {
                "subtopics": [
                    {
                        "resources": [
                            {
                                "_id": "5b857a91c346783a24cbdbb2",
                                "subtopic_id": "5b857a6ec346783a24cbdbb1",
                                "title": "Udemy Course",
                                "link": "https://udemy.com",
                                "concluded": false,
                                "__v": 0
                            }
                        ],
                        "_id": "5b857a6ec346783a24cbdbb1",
                        "title": "Variables",
                        "percentage_concluded": 0,
                        "topic_id": "5b857a21c346783a24cbdbb0",
                        "__v": 0
                    }
                ],
                "_id": "5b857a21c346783a24cbdbb0",
                "maintopic_id": "5b8565b90c927b2c47df7d9d",
                "title": "Python",
                "percentage_concluded": 0,
                "__v": 0
            }
        ],
        "_id": "5b8565b90c927b2c47df7d9d",
        "title": "Programming Languages",
        "percentage_concluded": 30,
        "__v": 0
    }
]

I want to start the React part, but I am really not sure how to structure it, I mean, should I create 1 component to handle the whole amount of data requested or I should create a single component for each moving part? 我想启动React部分,但是我真的不确定如何构造它,我的意思是我应该创建1个组件来处理请求的全部数据,还是应该为每个运动部分创建一个组件? Like... a component for MainTopics, one for Topics, one for SubTopics and one for each Resource. 就像... MainTopics的一个组件,Topics的一个组件,SubTopics的一个组件,每个Resource的一个组件。

So far, I have the following Reac code: 到目前为止,我有以下Reac代码:

App.js
components/
  Learning.js
  Resource.js
  Header.js

The main app file App.js 主应用程序文件App.js

import React, { Component } from 'react';
import Header from './components/Header';

import 'bootstrap/dist/css/bootstrap.min.css';
import './App.css';
import Learning from './components/Learning';

import './index.css';

class App extends Component {
  render() {
    return (
      <div className="App">
        <Header branding="Learn Tracker"/>
        <div className="container">
          <Learning />
        </div>
      </div>
    );
  }
}

export default App;

The other Learning.js : 另一个Learning.js

import React, { Component } from 'react'
import Resource from './Resource';
import axios from 'axios';


class Learning extends Component {
    constructor(props){
        super(props);
        this.state = {
            resource: [{}]
        }
        this.fetchData();
    }

    fetchData(){
        axios.get('/api/all')
            .then(result => {
                this.setState({resource: result.data});
            })
            .catch(err => {
                console.log(err);
            });
    }

    render() {
        const {resource} = this.state;
        resource.map((resource) => {
            return (
                <Resource resource={resource} />
            )
        });
        return(
            <div>
                {resource}
            </div>
        );
    }
}

export default Learning;

The Resource.js : Resource.js

import React, { Component } from 'react';
import PropTypes from 'prop-types';

class Resource extends Component {
  render() {
      const {resource} = this.props;
    return (
        <div className="card mb-3">
        <div className="card-header">
          <h4>{ resource[0].maintopic.title }</h4>
        </div>
        <div className="card-body">
            <h4 className="card-title">{ resource[0].maintopic.topic.title }</h4>
          <ul className="list-group">
            <li className="list-group-item">
            { resource[0].maintopic.topic.subtopic.title }
              <div className="card-body">
                <ul className="list-group list-group-flush">
                  <li className="list-group-item">Title: { resource[0].maintopic.topic.subtopic.resources[0].title }</li>
                  <li className="list-group-item">Link: { resource[0].maintopic.topic.subtopic.resources[0].link }</li>
                  <li className="list-group-item">Concluded: { resource[0].maintopic.topic.subtopic.resources[0].concluded }</li>
                </ul>
              </div>
            </li>
          </ul>
        </div>
      </div>
    )
  }
}

Resource.propTypes = {
    resource: PropTypes.object.isRequired
}

export default Resource;

And finally the Header.js : 最后是Header.js

import React from 'react'
import PropTypes from 'prop-types';

import 'bootstrap/dist/css/bootstrap.min.css';
import '../App.css';
import '../index.css';

const Header = props => {
    const { branding } = props;

    return (
      <nav className="navbar navbar-expand-sm navbar-dark bg-primary mb-3 py-3">
        <div className="container">
            <a href="/" className="navbar-brand">{branding}</a>
            <div>
                <ul className="navbar-nav mr-auto">
                    <li className="nav-item">
                        <a href="/" className="nav-link">Home</a>
                    </li>
                    <li className="nav-item text-white"><p className="nav-link"><span className="branco">|</span></p></li>
                    <li className="nav-item">
                        <a href="/" className="nav-link">About</a>
                    </li>
                </ul>
            </div>
        </div>
      </nav>
    )
}

Header.defaultProps = {
    branding: "Learning Tracker"
}

Header.PropTypes = {
    branding: PropTypes.string.isRequired
}
export default Header;

Please, help me to understand how I could come to the best solution for the structure of the application. 请帮助我了解如何为应用程序结构提供最佳解决方案。

Thank you in advance. 先感谢您。

Best regards. 最好的祝福。

I think the best and the easiest way to arrange your file structure in react is by use of stand-alone components . 我认为,在React中安排文件结构的最佳和最简便的方法是使用独立组件 Under this approach, you structure your app in the smallest units (components) possible. 通过这种方法,您可以以最小的单元(组件)构建应用程序。 These components will contain all they need to run anywhere. 这些组件将包含在任何地方运行所需的全部组件。 The main advantage of this approach is that it encourages a high level of code reusability. 这种方法的主要优点在于,它可以提高代码的可重用性。

If you were to pluck out a component and plug it in in a totally different app, it would run exactly the same way it used to run in the previous app. 如果您要拔出一个组件并将其插入完全不同的应用程序中,则其运行方式将与以前的应用程序中的运行方式完全相同。 Below how you could structure your app; 下面介绍如何构建应用程序;

 ├── src │ ├── components // Dumb components should go here -> they should be stand-alone components │ │ ├── App // App should should render all the main topics │ │ │ ├── index.js // Component logic and jsx │ │ │ ├── index.test.js // Component tests │ │ │ ├── index.css // Component styles │ │ ├── Header // All components should have their own index.js and index.test.js files │ │ │ ├── index.js // Component logic and jsx │ │ │ ├── index.test.js // Component tests │ │ │ ├── index.css // Component styles │ │ ├── MainTopic // MainTopic should be a component on its own because it's repeated. It's in an array. │ │ │ ├── index.js // Component logic and jsx │ │ │ ├── index.test.js // Component tests │ │ │ ├── index.css // Component styles │ │ ├── SubTopic // SubTopic should be a component on its own because it's repeated. It's in an array. │ │ │ ├── index.js // Component logic and jsx │ │ │ ├── index.test.js // Component tests │ │ │ ├── index.css // Component styles │ │ ├── Topic // Topic should be a component on its own because it's repeated. It's in an array. │ │ │ ├── index.js // Component logic and jsx │ │ │ ├── index.test.js // Component tests │ │ │ ├── index.css // Component styles │ ├── index.test.js // Tests for non-components files │ ├── index.js │ ├── routes.js // All routes should be registered here 

It all depends on the application size and on the additional technologies (eg Redux) you might want to add to your app (now) or might considering using (adding on) in the future. 这全都取决于应用程序的大小以及您可能想添加到应用程序中的其他技术(例如Redux)或将来考虑使用(添加)。 React doesn't have opinions on how you put files into folders. React对如何将文件放入文件夹没有意见。

With that being said, here are some examples you might consider: 如此说来,您可以考虑以下示例:

Grouping by features or/ and routes 按功能或/和路线分组
[ put your CSS, JS, and other files together inside folders grouped by feature or route. [将CSS,JS和其他文件放到按功能或路线分组的文件夹中。 ] ]

  common/
  Avatar.js
  Avatar.css
  APIUtils.js
  APIUtils.test.js
feed/
  index.js
  Feed.js
  Feed.css
  FeedStory.js
  FeedStory.test.js
  FeedAPI.js
profile/
  index.js
  Profile.js
  ProfileHeader.js
  ProfileHeader.css
  ProfileAPI.js

Grouping by file types 按文件类型分组
[ group similar files together ] [将相似文件分组]

api/
  APIUtils.js
  APIUtils.test.js
  ProfileAPI.js
  UserAPI.js
components/
  Avatar.js
  Avatar.css
  Feed.js
  Feed.css
  FeedStory.js
  FeedStory.test.js
  Profile.js
  ProfileHeader.js
  ProfileHeader.css

These are some basic examples of simple apps. 这些是简单应用程序的一些基本示例。 But if your app starts to grow larger you would consider dividing your components into separate folders depending on what task they are doing, making containers for your components and putting them inside of a separate folder. 但是,如果您的应用开始变得越来越大,您可以考虑根据组件正在执行的任务将它们划分到单独的文件夹中,为组件创建containers并将它们放置在单独的文件夹中。 If you're using something like scss complainer you would probably make a separate folder for the styles and divide compiled CSS files from the scss ones. 如果您使用的是类似scss ,则可能会为样式创建一个单独的文件夹,并将已编译的CSS文件与scss Additionally, if you use something like Redux you would have your actions & reducers folders, and probably a separate store folder (where you would configure your react-redux store ). 另外,如果使用Redux东西,则将有您的actionsreducers文件夹,可能还有一个单独的store文件夹(您可以在其中配置react-redux store )。 That folder structure would go something like this: 该文件夹结构将如下所示:

/src
   /components     // where you put and divide all your components
      /posts       // folder containing all files relevant to your eg post feature
      /likes       // likewise, a folder containing all files relevant to your likes feature
      /home
   Header.js      // some of your other files that are used everywhere 
   Footer.js
   App.js        // your main  App.js file, if you decide to put it inside of your 'components' folder 
   ...
  /containers     // where you would put your containers, get all the data and pass it down to components as props 
     /HomeContainer.js
     /PostContainer.js
     /LikesContainer.js                               
  /actions        // all of for your action creators and types
  /reducers       // all of for your reducers, including your root reducer
  /utils          // all your helper methods, eg for your auth flow
  /styles         // your css (or/ and scss) files
  /assets         // your logos, images, and other static files
  ...etc
  index.js        // Your main index.js file inside of the root 'src' folder

I also suggest reading this: Thinking in React . 我还建议阅读以下内容: 在React中思考
It might give you slight hints on how to approach creating apps using React . 它可能会给您一些关于如何使用React来创建应用程序的提示。

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

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