将新道具合并为州的正确方法

时间:2019-05-18 13:27:40

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

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

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

目前,我只有一些用例,这些用例来自网站的内置通知系统,它将提供一个功能,可以将外部事件作为通知发送到您自己的日历中。 但是,我可能想通过我的套接字服务器(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,如果是,则将作为道具向下发送的新事件合并到日历的当前事件中。 3)然后,它运行一个回调函数(nextProps.reset()),将propInput重置为FALSE,这将触发另一次getDrivedStateFromProps运行,但是这次返回null并且不会导致新的setState。

这是我自己的梦想解决方案,如何将新事件从redux商店推送到此日历包装器。这似乎是非正统的,但对我来说,这是唯一的途径,可以使纯redux和所有保存在redux中的东西都具有中间立场,并且使每个组件具有局部状态。

是否有技术上更好,更完善的方法来解决此问题?

谢谢。

2 个答案:

答案 0 :(得分:1)

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

您甚至不需要以状态存储此时间戳-无需使用getDerivedStateFromProps“无论原因为何,均在每个渲染器上触发” )-经典解决方案:< / p>

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对象引用更改。

答案 1 :(得分:0)

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

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

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