当业务逻辑不在组件之外时,在React组件中进行状态管理

时间:2018-10-19 10:46:31

标签: javascript reactjs react-state-management

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

  • Map渲染了一个带有视觉标记的地图,该视觉标记表示用户提供的地址。

  • List组件包含所有添加的地址作为列表项。

  • Input允许用户添加新地址(按照我的说法,该地址称为 LocationPoint )。

现在,App使locations数组保持所有这些地址( LocationPoints )的状态,并将该数组传递给所有子组件。

带有LocationPoints的操作(添加/移动/更新/删除LocationPoint)被取出来分离功能,因为它们非常通用,以后可能会在其他地方重用。

但是因为那些函数不知道状态的存在,所以我不得不创建某种“提供者”函数来调用那些动作(addLocationPoint,deleteLocationPoint等)。例如。 addLocationPoint函数必须在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的合适时机?

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

1 个答案:

答案 0 :(得分:0)

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

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

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

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

Redux动作创建者使用了类似的想法。

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