【问题标题】:Proper Way to merge new props into state将新道具合并到状态的正确方法
【发布时间】:2019-05-18 13:27:39
【问题描述】:

我目前正在使用 react-big-calendar 开发日历组件。

我目前有一个 Wrapper,它可以从数据库中提取数据并将其发送到日历组件中。但是,我正在开发一项功能,即可以从任何地方向该组件“发送”日历事件。

目前我只有用例,它来自网站的内置通知系统,将有一个功能可以将作为通知发送的外部事件添加到您自己的日历中。 但是,我可能想通过我的套接字服务器 (socket.io) 从另一个 Web 应用程序将事件推送到用户日历。

从技术上讲,我不确定什么是“正确”的反应方式。

我现在的做法是我添加了

 static getDerivedStateFromProps(nextProps, prevState){
    if(nextProps.propInput === true){
        nextProps.reset()
        return {events : {...prevState.events, ...nextProps.events}}
    } else return null
}

在我的 CalendarWrapper 中,它基本上为我做了以下事情: 1)我更新发送到包装器的道具,无论是从父组件还是从redux商店(我将使用第二个) 2) 这会触发 getDrivedStateFromProps 并检查它是否将 propInput 接收为 true,如果是这样,它将作为 props 向下发送的新事件合并到日历的当前事件中。 3)然后它运行一个回调函数(nextProps.reset()),将propInput重置为FALSE,这会触发getDrivedStateFromProps的另一次运行,但这一次返回null并且不会导致新的setState。

这是我自己设想的如何将新事件从 redux 商店推送到这个日历包装器的解决方案。这似乎很不正统,但对我来说,这是在纯 redux 中找到中间立场的唯一方法,所有内容都保存在 redux 中,并且每个组件都有本地状态。

有没有一种技术上更好、性能更好的方法来解决这个问题?

提前致谢。

【问题讨论】:

  • 纯redux?使用事件有效负载调度新操作 ... 减速器 ... 更新状态 ... 更新连接的组件 - 不需要其他魔法(握手?)?
  • 是的,这正是我想要避免的。我对整个例程不感兴趣,您会看到这个 react-big-calendar 应用了 dnd 和类似的不错的功能,每次拖放时都必须更新 react 存储会很慢(我相信)即使我散列数组,我已经做过了。

标签: javascript reactjs redux react-big-calendar getderivedstatefromprops


【解决方案1】:

我会保存一个时间戳(而不是布尔值 propInput),并将新事件发送到 redux。比较“上次更新时间”就足以做出更新决定 - 无需清除 propInput 标志(没有 reset() 调用...减速器...等)。

您甚至不需要将此时间戳存储在状态中 - 无需使用 getDerivedStateFromProps“在每次渲染时触发,无论原因如何”) - 经典解决方案:

componentDidUpdate(prevProps) {
  if (this.props.newEventsTime !== prevProps.newEventsTime) {
    setState({events : {...this.state.events, ...this.props.newEvents}})
  }
}

更优化的应该是

shouldComponentUpdate(nextProps, nextState) {
  if (nextProps.newEventsTime !== this.props.newEventsTime) {
    setState({events : {...this.state.events, ...this.props.newEvents}});
    return false; // no render needed in this pass
  }
  return (nextState.events === this.state.events) ? false : true;
}

- 更新 events 对象引用更改。

【讨论】:

  • 这实际上是一种更顺畅的方法。 componentDidUpdate 比 getDrivedStateFromProps 有什么好处?他们在每次渲染时都会被调用,不是吗?
  • getDrivedStateFromProps 无法访问 prev 道具,您应该将时间存储在 state 中以进行比较
【解决方案2】:

您必须返回 prevState 与新状态的合并,如下所示:

static getDerivedStateFromProps(nextProps, prevState){
if(nextProps.propInput === true){
    nextProps.reset()

    return {...prevState, ...{ 
               events : nextProps.events
           }
    }
} else return null
}

【讨论】:

  • 除了它并没有真正回答问题之外,这与我当前的合并有什么不同?它的工作方式类似于 setState() ,您可以返回一个键/值对并将其合并到状态中。不正确吗?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-07-04
  • 1970-01-01
  • 2020-10-23
  • 2022-01-10
  • 2016-07-02
相关资源
最近更新 更多