我正在重写一个小应用程序,试图更好地理解React。我正在尝试确定共享“单例”数据的“正确”/最有效的方法 - 例如,在登录时已经过适当身份验证的用户。
现在,父“application”组件在其状态中具有user
属性,我将其作为prop传递给子组件:
<Toolbar user={this.state.user} />
<RouteHandler user={this.state.user}/>
(我正在使用react-router)。这是有效的,在像这样的只读情况下,并不可怕。但是,我的实际登录表单组件(这是一个路由,并且将在RouteHandler
内),需要一些方法来“设置”新的用户数据,所以我还需要传递一些回调:
<RouteHandler onAuthenticated={this.setUser} user={this.state.user}/>
不是一个大问题,除了现在这个方法可用于RouteHandler
处理的每个“路线”。
我一直在阅读,似乎唯一的选择是EventEmitter
或Dispatch
式系统。
我错过了更好的方法吗?事件发射器/调度器系统是否值得使用,当这个小应用程序中只有一两个用途?
答案 0 :(得分:2)
React Context提供了一种通过组件树传递数据的方法,而不必在每个级别手动传递道具。通过上下文,嵌套在FILES_${PN} += "${base_prefix}/home/root/mydir/*"
下的每个组件都可以访问数据,但是您需要显式读取值。
我建议将React Hooks与useContext一起使用。一种实现方法是将上下文的mydir
设置为具有setter和getter函数的Provider
。
value
答案 1 :(得分:0)
对于单身人士 - 您可以为用户服务创建单独的模块,并将其导入模块,您可以在模块中定义需要它的组件。
其他非常相似但功能更强大的选项是使用DI容器 - 将您的反应组件定义为DI容器中的服务,并依赖于其他服务,例如用户数据。这将更适合于通用(同构)应用程序 - 因为,您将能够轻松地用特定实现替换依赖项,或者当您需要为单独的范围创建单独的实例时(例如用户会话服务器端)。 / p>
此外,如果使用这种方法,我建议将纯反应组件与逻辑分开 - 您可以创建单独的纯组件来接收所有数据,并将回调作为道具,而不是在DI容器中创建将包装它的HoC组件将传递所需的数据和回调。
如果你需要DI容器 - 它们有很多,但我会建议看看角度2 di容器,或者如果你想要更简单的东西 - 下面我参考了我的项目,它有非常简单但功能强大的DI受角度2 DI的启发(很容易从该项目中拉出 - 只需一个文件+测试)。
关于通知组件有关更改和组织异步逻辑 - 您仍然需要类似EventEmitter的内容来通知组件有关更改,并且您需要为组件编写生命周期回调以订阅/取消订阅更新...您可以通过以下方式执行此操作手或创建mixin或HoC来缩短它。
但是从我的角度来看,有更好的方法 - 尝试反应式编程,特别是RxJS。反应非常好。
如果您对连接Rx和React的选项感兴趣 - 请看一下gist https://gist.github.com/zxbodya/20c63681d45a049df3fc,同时通过订阅上面提到的EventEmitter实现HoC组件也会有所帮助。
我有一个项目,用于创建isomorphic(呈现服务器端,而不是相同的html重用客户端)小部件与反应。 它有DI容器来传递依赖关系,它使用RxJS来管理异步逻辑:
答案 2 :(得分:0)
一种方法是订阅从数据模型中发出的Observable。
Router.run(routes, Handler =>
Model.subject.subscribe(appState =>
React.render(
<Handler {...appState}/>,
document.getElementById('app')
)
)
);
... appState是来自可观察数据(在本例中为模型)的数据,使这些成为您的道具,以便您可以将它们提供给应用程序,如下所示
<RouteHandler {...this.props} />
任何子组件都可以使用this.props
答案更复杂,但是如果你看一下RxJS+React,你将得到一个完整的简单数据流示例