【问题标题】:What is the proper way to control react components based on redux state基于redux状态控制反应组件的正确方法是什么
【发布时间】:2019-12-22 09:26:39
【问题描述】:

我认为这更像是一个概念/架构问题,但我将包含代码示例以帮助解释该问题。我有一个规范化的 redux 状态,其中实体状态切片如下所示:

entities: {
    projects: {
        [id]: {...},
        [id]: {...},
        ...
    },
    assignments: {
        [id]: {...},
        [id]: {...},
        ...
    }
}

一个单独的任务看起来像这样:

    {
        id: 1,
        name: 'assignment 1',
        status: 'active',
        deadline: '01-01-2020'
    }

我从后端数据库获取这些数据。我正在尝试找出正确的方法来处理更新这些数据、保持 UI 响应以及保持我的 redux 状态与后端同步的过程。

一个具体的例子是一个反应组件,用于显示一个具有选择器/单选按钮来改变状态的单个分配:

    const statusOptions = {
        'active',
        'pending',
        'complete'
    }

我能看到的选项是:

1) 将选择器的值设置为props.assignment.status 值,并在选择器/选择器的 onChange 中调度一个updateAssignment() 操作,其中一个 saga/thunk 发送 POST 请求并立即触发一个fetchAssignment() 操作这将发送一个 GET 请求并更新 redux 状态,然后组件将重新渲染。

这样做的问题是 redux 更新时间太长,因此 UI 显得迟钝,并且受控输入将恢复为旧选择,直到传入新的 props。

2)根据redux状态设置本地组件状态如下:

    state = { status: this.props.assignment.status }

然后根据本地状态设置选择器的值,这将在值更改时提供近乎即时的 UI 更新。

我在这里看到的问题是我很确定这是一个反应反模式,我必须使用 getDerivedStateFromProps() 或类似的东西来确保本地状态与 redux 状态保持同步。另外,我真的很喜欢“单一事实来源”的想法,我觉得这个选项会使它失效。

3) 根据props.assignment.status设置picker的值,在picker的onChange handler中克隆assignment对象,更新status属性,然后立即发送updateAssignment()动作合并本地创建的assignment 对象进入状态。

之后将 POST 请求发送到服务器,如果它以某种方式失败,则将 redux 状态恢复到先前的状态,基本上删除本地添加的 assignment 对象。这似乎有点骇人听闻?

是否有任何公认的最佳实践来更新 redux 数据,同时保持单一的事实来源、简洁的 UI 和干净的代码?

【问题讨论】:

    标签: javascript reactjs react-native redux redux-saga


    【解决方案1】:

    在我看来,(2) 的第一部分是正确的。

    在 ComponentDidMount 中(或者更好的是,在 App.js 中,当应用程序启动时)您从数据库中获取数据到 redux 状态,并从中设置本地状态。

    然后你在本地维护数据,并派发适当的操作来更新 redux 状态和数据库。

    在 shouldComponentUpdate 中,您需要防止在此 redux 更新之后发生更新:您将检查 props 的值是否已更改。

    在 componentDidUpdate 中,如果 props 发生变化,您将更新状态。

    最后需要注意的是在其他智能手机上运行的应用程序的其他实例或其他数据源(如果可能发生)发生数据库更改后获取数据更新。例如,在 firebase 中,您可以通过监听相关的应用程序更改来做到这一点。我不知道这是否与这里有关。

    【讨论】:

      猜你喜欢
      • 2018-08-08
      • 2017-04-19
      • 2018-12-22
      • 1970-01-01
      • 1970-01-01
      • 2020-01-15
      • 1970-01-01
      • 2016-12-29
      • 2020-12-03
      相关资源
      最近更新 更多