【问题标题】:How to proper split React application components如何正确拆分 React 应用程序组件
【发布时间】:2018-09-08 18:10:47
【问题描述】:

我通过创建应用程序来学习 React,但我认为我低估了它的复杂性。让我与您分享一下我是否正确:

这个想法是创建一个 React 应用程序来跟踪我想学习的主题。我创建了以下结构:

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

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
            }
            ]
        }
        ]
    }
    ]
}

每个主题都称为MainTopic,它下面有很多主题,比如:JavaScript有NodeJS、数据结构和算法作为主题,Express是Node的子主题等等……

我有一个 NodeJS API 服务 JSON 来获取已经存储在数据库中的文档的完整列表以及它的每个特定部分,MainTopics,来自给定 MainTopic 的主题等等......这里你是 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
    }
]

我想启动 React 部分,但我真的不知道如何构建它,我的意思是,我应该创建 1 个组件来处理请求的全部数据量,还是应该为每个移动部分创建一个组件?比如...一个用于 MainTopics 的组件,一个用于 Topics,一个用于 SubTopics,一个用于每个 Resource。

到目前为止,我有以下 Reac 代码:

App.js
components/
  Learning.js
  Resource.js
  Header.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;

另一个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;

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;

最后是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;

请帮助我了解如何为应用程序的结构找到最佳解决方案。

提前谢谢你。

最好的问候。

【问题讨论】:

    标签: javascript node.js mongodb reactjs software-design


    【解决方案1】:

    我认为在 react 中安排文件结构的最佳和最简单的方法是使用独立组件。在这种方法下,您可以以最小的单元(组件)来构建您的应用程序。这些组件将包含它们在任何地方运行所需的一切。这种方法的主要优点是它鼓励高水平的代码可重用性。

    如果您要提取一个组件并将其插入到一个完全不同的应用程序中,它的运行方式将与以前在以前的应用程序中运行的方式完全相同。下面是您如何构建您的应用程序;

    ├── 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

    【讨论】:

      【解决方案2】:

      这完全取决于应用程序的大小以及您可能想要添加到您的应用程序(现在)或将来可能考虑使用(添加)的其他技术(例如 Redux)。 React 对如何将文件放入文件夹没有意见。

      话虽如此,以下是一些您可以考虑的示例:

      按功能或/和路线分组
      [ 将您的 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
      

      按文件类型分组
      [将相似的文件组合在一起]

      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
      

      这些是一些简单应用的基本示例。但是,如果您的应用程序开始变大,您会考虑根据组件执行的任务将组件分成单独的文件夹,为您的组件创建 containers 并将它们放在单独的文件夹中。如果您使用类似scss 投诉者的东西,您可能会为样式创建一个单独的文件夹,并将编译后的CSS 文件与scss 文件分开。此外,如果您使用Redux 之类的东西,您将拥有您的actions 和reducers 文件夹,并且可能还有一个单独的store 文件夹(您可以在其中配置您的react-redux store)。该文件夹结构将如下所示:

      /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
      

      我还建议阅读以下内容:Thinking in React。
      它可能会给您一些关于如何使用 React 创建应用程序的提示。

      【讨论】:

      • 感谢您的链接,它真的很有帮助!
      猜你喜欢
      • 2021-12-27
      • 2015-02-08
      • 2018-09-18
      • 2021-09-04
      • 2014-06-11
      • 2021-04-19
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多