首页 > 解决方案 > 当业务逻辑在组件之外时,React 组件中的状态管理

问题描述

那里!App 组件是三个不同组件的容器:

现在,所有这些地址( LocationPointsApp )保持locations数组处于状态,并将该数组传递给所有子组件。

对 LocationPoints 的操作(添加/移动/更新/删除位置点)被提取到单独的函数中,因为它们非常通用,以后可能会在其他地方重用。

但是因为这些函数不知道状态的存在,所以我必须创建某种“提供者”函数来调用这些操作(addLocationPoint、deleteLocationPoint 等)。例如addLocationPointfunc 必须在里面调用App.addLocationPoint

下面的例子应该更好地解释我在说什么。注意:片段不起作用,因为它不是真正的实现。

// Adds a new location point
const addLocactionPoint = (locations: array, address: string) => {
  // ...
  return updatedLocations;
}

class App extends React.Component {
  constructor() {
    this.state = {
      locations: [],
    }

    // bind addLocPoint, etc.
  }

  addLocPoint(address) {
    this.setState(state => {
      addLocactionPoint(state.locations, address);
    });
  }

  // ...

  render() {
    return (
      <Input onSubmit={ this.addLocPoint } />
      <List 
        onDrag={ this.moveLocPoint }
        onDelete={ this.deleteLocPoint } 
      />
      <Map data={ this.state.locations } />
    );
  }
}

我的方法可以被认为是一种好的做法吗?或者还有其他方法可以减少 App 组件中的逻辑数量并避免在不使用状态管理库(MobX、Redux 等)的情况下创建那些“提供者”。也许我认为是引入 Redux 或 MobX 的合适时机?

我将非常感谢您提供有关此问题的建议或建议或链接。

标签: javascriptreactjsreact-state-management

解决方案


这已经足够好了,这就是在没有状态管理库的 vanilla React 中通常如何维护全局状态。上下文 API 还可用于将状态传递给嵌套组件。

可以改变的是,更新状态的函数实际上可以被提取并用作setState 高阶更新函数:

const addLocationPoint = (address) => ({ location }) => {
  // ...
  return updatedLocations;
}

class App extends React.Component {
  ...
  addLocPoint(address) {
    this.setState(addLocationPoint(address));
  }
  ...

Redux action creators 中使用了类似的想法。

为了让状态更新器提供真正的改进,它们必须被移动到另一个模块。在这种情况下,它们可以与使用它们的组件分开测试,并jest.mock在使用它们的组件中进行模拟。


推荐阅读