如何在 react / flux / redux 中处理子组件完成事件
how to handle subcomponent completion eventsin react / flux / redux
我正在 react/redux 中设计一个应用程序,我是 flux/redux 和单向模式的新手。我 运行 遇到了一个我不确定如何在单向架构中正确解决的问题
我想用可能出现在应用程序不同部分的用户注册表单示例来说明问题。请注意,核心问题是关于是否以及在何处处理子组件完成事件,UserRegistration
只是一个示例。
假设我有一个组件 UserRegistration
将呈现为表单。该组件将处理自己的提交操作,其中可能包括对服务器端点的一些异步调用,最后应该导致对 store/state 的修改(例如添加新的用户数据)。
用户流程如下:
- 用户点击 'register' 按钮
- 用户看到注册表
- 用户输入数据并点击 'submit'
- 用户注册表消失
我想在应用程序的不同位置包含此 UserRegistration
表单。
假设我想显示基于路由 /register
的注册表单,在成功注册后我想路由回 /
。
对我来说(来自非单向世界)的直观操作看起来像这样
function MyApp() {
const isRegisterRoute = //... somehow check if /register is active
return (
<button onClick={ () => { routeTo('/register') }}>register</button>
{
isRegisterRoute && (
<UserRegistration // handles actual registration internally (network calls and store modification)
onCompletion={ () => { routeTo('/' } } // pass completion handler which will route back to initial path
/>
)
}
)
}
这会解决问题,但我想知道为这种具有复杂流程的组件设置回调是否是单向架构中的反模式。
- 一个问题是回调基本上颠倒了方向,不再是单向的。
- 另一个问题是我必须将
onCompletion
处理程序传递到我的组件内的链中,以便在注册完成后执行它。处理程序的这种传递感觉不干净,因为它泄漏到很多地方。
另一方面,我不想处理返回到 UserRegistration
组件内的“/”的路由,因为成功路由或操作可能会有所不同,具体取决于我使用它的位置,所以我想要要与组件解耦的逻辑。
在 flux 中,appropriate/best-practice 解决上述问题的方法是什么?
根本不是数据流
这不是反模式,因为我没有看到从子组件到父组件的任何数据流,例如
<SubComponent onComplete={data=>this.setState({data})}/> // not good
重新路由到另一个路由器是逻辑,next router
是 属性 传递给 UserRegistration
组件,所以它与
相同
<UserRegistration nextRouteOnComplete="/"/> // property
并处理 UserRegistration 中的 routeTo
逻辑。
一个函数可以是动态的,一定要确保没有数据传递给回调函数,回调函数是为了处理完成后的逻辑,不应该传递任何数据,数据更新应该遵循单向数据流,
dispatch action
-> reduce action
-> mutate state
-> rerender
我正在 react/redux 中设计一个应用程序,我是 flux/redux 和单向模式的新手。我 运行 遇到了一个我不确定如何在单向架构中正确解决的问题
我想用可能出现在应用程序不同部分的用户注册表单示例来说明问题。请注意,核心问题是关于是否以及在何处处理子组件完成事件,UserRegistration
只是一个示例。
假设我有一个组件 UserRegistration
将呈现为表单。该组件将处理自己的提交操作,其中可能包括对服务器端点的一些异步调用,最后应该导致对 store/state 的修改(例如添加新的用户数据)。
用户流程如下:
- 用户点击 'register' 按钮
- 用户看到注册表
- 用户输入数据并点击 'submit'
- 用户注册表消失
我想在应用程序的不同位置包含此 UserRegistration
表单。
假设我想显示基于路由 /register
的注册表单,在成功注册后我想路由回 /
。
对我来说(来自非单向世界)的直观操作看起来像这样
function MyApp() {
const isRegisterRoute = //... somehow check if /register is active
return (
<button onClick={ () => { routeTo('/register') }}>register</button>
{
isRegisterRoute && (
<UserRegistration // handles actual registration internally (network calls and store modification)
onCompletion={ () => { routeTo('/' } } // pass completion handler which will route back to initial path
/>
)
}
)
}
这会解决问题,但我想知道为这种具有复杂流程的组件设置回调是否是单向架构中的反模式。
- 一个问题是回调基本上颠倒了方向,不再是单向的。
- 另一个问题是我必须将
onCompletion
处理程序传递到我的组件内的链中,以便在注册完成后执行它。处理程序的这种传递感觉不干净,因为它泄漏到很多地方。
另一方面,我不想处理返回到 UserRegistration
组件内的“/”的路由,因为成功路由或操作可能会有所不同,具体取决于我使用它的位置,所以我想要要与组件解耦的逻辑。
在 flux 中,appropriate/best-practice 解决上述问题的方法是什么?
根本不是数据流
这不是反模式,因为我没有看到从子组件到父组件的任何数据流,例如
<SubComponent onComplete={data=>this.setState({data})}/> // not good
重新路由到另一个路由器是逻辑,next router
是 属性 传递给 UserRegistration
组件,所以它与
<UserRegistration nextRouteOnComplete="/"/> // property
并处理 UserRegistration 中的 routeTo
逻辑。
一个函数可以是动态的,一定要确保没有数据传递给回调函数,回调函数是为了处理完成后的逻辑,不应该传递任何数据,数据更新应该遵循单向数据流,
dispatch action
-> reduce action
-> mutate state
-> rerender