我有一个搜索面板的网页。搜索面板有几个输入字段:ID,大小,.
我想要的是当用户设置搜索值(例如:id=123和size=45)并按下搜索按钮时:
- Redux reducer中的searchState应该更新为新的搜索值(id=123和size=45)
- URL应该改为“http://mydomain/home?id=123&size=45“
另一方面,如果用户将URL更改为http://mydomain/home?id=111&size=22,则: - reducer中的searchState应该使用新的搜索值(id=111和size=22)进行更改
- UI搜索面板输入应更新为新值(id=111和size=22)
如何达到目标?我应该使用什么路由器(react-router,redux-router,react-router-redux或其他)?
7条答案
按热度按时间p8h8hvxi1#
我建议直接使用React Router,不要在Redux中保留
searchState
。React Router会将URL参数注入到你的组件中,你可以在mapStateToProps(state, ownProps)
中使用它们来计算最终的props。如果你真的想看到路由变化作为动作,你可以使用react-router-redux进行双向同步,但它不会给予你状态中的参数-只是当前位置。如果你想记录和重放动作,并让URL栏在重放时更新,这是唯一的用例。
这绝不是必需的-在大多数情况下,**直接使用React Router就足够了。
yyhrrdl82#
因此,我刚刚发布了redux-query-sync,让您提供一个选择器函数,用于从状态中选择一个值,然后将其暴露在您指定的参数名称的窗口位置。(例如,当应用程序初始加载时),您可以提供一个action creator,它将被传递参数值,因此您的reducer可以相应地更新状态。
ukqbszuj3#
我最近也完成了我公司应用程序的这个功能。我们想在URL中添加不同的搜索查询。
我想在这里分享几件事:
1)我们使用了Redux store和react-router。由于我们还使用了Typescript,因此我们最终使用了react-router中的RouteWebsentProps来使用this.props.history.push()来更新URL。
2)我们将所有搜索查询保留在Redux store中。更新Redux store和URL的工作流程如下:
在app中选择一些过滤选项=> Dispatch actions to update filtering state in Redux store => update the URL
3)最后,我们还希望用户能够输入带有查询参数的URL,它将更新应用程序中的所有过滤器。要做到这一点,工作流程甚至更简单:
用户输入URL => dispatch actions,通过URL中的查询参数更新Redux状态。Redux状态的更新将自动导致应用中的重新渲染,所有过滤器都将更新。
因此,这里最重要的事情是始终保持Redux状态和URL彼此同步。
d6kp6zgx4#
这是我处理第一种情况的方法:
this.context.router.push()
,并将带有正确查询字符串的url传递给它。我不确定这是否是正确的方法,我发现它比首先更新URL更好,因为在我看来,查询字符串应该是状态的反映,而不是状态的主人。
至于反向的情况,我真的不确定。似乎手动设置URL会触发完全重新加载,但我可能搞错了。
至于使用哪个路由器,我使用的是React Router本身。我并没有真正发现使用其他路由器的价值,this discussion对我来说是决定性的。
htzpubme5#
我最近完成了一个类似的问题。我使用MobX作为我的商店和redux-router作为我的路由器。(我用react-router做得很好,但我需要在组件之外分派一个push动作- redux作为全局商店在这里工作得很好)
我的解决方案与cantera所描述的类似--我的路由器状态仅仅是表单状态的一个反映。这有一个额外的好处,那就是不必放弃表单状态,而完全依赖于路由器状态。
在第一种情况下,
1)我像往常一样更新表单输入,这会触发结果组件中的重新呈现。
2)在results组件的
componentDidUpdate()
中,我使用表单props构造更新后的查询字符串。3)我将更新后的查询字符串推送到路由器状态。这纯粹是为了更新URL的效果。
对于第二方案所
1)在根
Route
组件上的onEnter
钩子中,我获取可用的查询字符串并将其解析为初始形式值。2)我用这些值更新我的存储。这只适用于第一次加载页面,也是路由器状态决定表单状态的唯一一次。
编辑:此解决方案不考虑当您返回浏览器历史记录时的情况,因为URL不会更新您的状态。
brjng4g36#
我推荐新的工具react-url-query,它可以非常直接地完成同步。
8cdiaqws7#
这里有一个解决方案,可以很好地控制浏览器url中的内容。
解决方案由以下部分组成:
queryStringSelector
-一个选择器,负责构建一个查询搜索字符串,并将其推送到浏览器的url中。它可以是智能的,也可以省略默认值。可以实现自定义序列化值,也可以只使用JSON.stringify
。getPartialStateFromQueryString
helper fn。它获取浏览器的查询字符串并将其解析为Partial<MyState>
。它应该支持所有由queryStringSelector
编码的字段,并且必须能够将字符串值解析回所需的结构。它不应该信任URL中的值,因为用户可能会编辑这些字符串。setStateFromPartialState
action。它获取存储(切片)的部分状态作为有效负载,并更新状态以匹配该部分状态。所有应与URL同步但不存在于部分状态对象中的值应首先重置为初始状态。useSyncWithUrl
自定义钩子,主要负责三个方面:第一,设置浏览器url的初始值,在组件挂载时存储,只做一次;第二,订阅状态变化,基本上就是消耗queryStringSelector
的输出,并推送更新到URL;第三,在URL变化时更新状态,简单来说,它订阅浏览器中的导航更改(“POP”事件)并相应地更新存储。请注意,它不会对PUSH
事件做出React,只是对“POP”事件做出React请务必记住,建议的方法只有在您使用商店作为真实来源时才有效。即您的应用应该将更改应用于商店,而不是URL以达到特定状态。URL仅在两种例外情况下被视为真实来源:1)初始化时2)当浏览器的向后导航发生时。但是,如果您使用应用程序自己的同步钩子示例导航到应用程序的其他部分,它仍然有效,因为无论您如何到达该状态,都会发生初始化阶段。
示例如下:
查询字符串选择器:
字符串
getPartialStateFromQueryString
辅助程序型
减速器作用
型
同步到url自定义挂钩:
型