React Context Folder hiarchy/架构?

Bry*_*der 8 javascript reactjs

我目前正在考虑通过 Redux 将 Context 实现到我们的一个应用程序中,但是,我似乎找不到任何关于大型应用程序的最佳结构的信息?

Redux 有一种定义的方式来创建减速器、动作等。使用 Context,我发现的所有内容都是通用的“创建提供者,将状态和方法都放在同一个文件中,然后使用消费者”。

TL;DR 有没有办法用 React Context 构建一个有利于长期和大规模应用程序的层次结构?

编辑:我想认为它们具有类似的结构化关系是不正确的。不幸的是,由于 AEM 的限制,我无法使用 Redux。然而,上下文确实有效,所以我希望能够用它构建一些结构。

noa*_*dev 7

首先,我认为这个问题不一定有正确或错误的答案,但我只会给你我的两分钱。

我目前正在重构一个 Web 应用程序,该应用程序每月为数百万个会话提供服务,并且正在内部阶段服务器上测试 redux 和上下文版本。

重要通知:

  • 我正在使用单一商店的方法
  • 它不是一个不断有全球商店更新的应用程序

到文件夹结构。我喜欢将我的商店放在项目的根目录中。对于基于 react-create-react-app 的 react 应用程序,/src它基本上由以下文件组成:

  • index.js // 一切都在这里“捆绑”
  • initialState.js // 为商店提供初始状态,例如来自服务器、缓存等。
  • methods/*.js // 包含基于应用程序中使用它们的部分的拆分方法(如果它可以拆分为单独的部分)

所以我的 index.js 很简单:

import React from 'react';
import storeMethods from './methods';
import initialState from './initialState';

// to start of experimenting with context
// i would keep all read and write key value
// pairs right here and split as the codebase
// grows and you realize you need more space
export const store = {
  ...initialState,
  ...storeMethods
}

export const StoreContext = React.createContext(store)
Run Code Online (Sandbox Code Playgroud)

storeMethods是所有捆绑出口methodsmethods/的文件夹。基本上它只是另一个包含键的对象,这些键的值是这样的:

export const methods = {
   showNavBar: function() {
      this.setState({ navBarOpen: true })
   }
}
Run Code Online (Sandbox Code Playgroud)

initialState与呈现应用程序的基本内容所需的键值对的表示一样多,或者永远不会改变。基本上是一些全局设置。来自服务器的初始状态正在我的应用程序的构造函数中添加到商店,就在我绑定词法范围之前。

store get 被抛出到相关的最外层 React 组件的状态,并用作应用程序状态,我将 store 的范围绑定到 React Components 词法范围。

然后我有一个高阶组件withContextConsumer,用于包装任何需要访问状态的 React 组件。HOC 将订阅的密钥作为 props 分发给包装的组件,并且可以作为只读或写入使用。

无论您最终如何使用 Context,请不要忘记,如果 Context Store 正在更新,任何 Consumer 都会自动调用它的 render 方法。为了在简单oldProps !== newProps级别上避免这种情况,您可以使用 PureComponents。对于更复杂的差异,您可以使用生命周期方法shouldComponentUpdate

编辑

基本应用程序结构

应用程序.js:

import React, { PureComponent } from 'react'
import { StoreContext, store } from './store'
import { bindScopeToFunction } from './helpers'

class App extends PureComponent {
   constructor(props) {
      super(props)
      const { initialState = {} } = props
      const boundStore = bindScopeToFunction(store, this)
      this.state = {...boundStore, ...initialState}
   }
   render () {
      return(
         <StoreContext.Provider value={this.state}>
            // in here you render all your app
            // routing, childcomponents etc
            // in any component where you need access
            // to the global store
            // wrap it in <StoreContext.Consumer> it has
            // the whole store as render prop
         </StoreContext.Provider>
      )
   }
}
Run Code Online (Sandbox Code Playgroud)

工作基本示例可以在这里找到https://codesandbox.io/s/pm85w4y6xm