如何同步 Redux 状态和 url 哈希标签参数
Posted
技术标签:
【中文标题】如何同步 Redux 状态和 url 哈希标签参数【英文标题】:How to sync Redux state and url hash tag params 【发布时间】:2016-08-11 21:06:26 【问题描述】:我们有一个讲座和章节列表,用户可以在其中选择和取消选择它们。这两个列表存储在一个 redux 存储中。 现在我们希望在 url 的 hash 标记中保留所选讲座 slug 和章节 slug 的表示,并且对 url 的任何更改也应该更改存储(双向同步)。
使用react-router 甚至react-router-redux 的最佳解决方案是什么?
我们真的找不到一些好的例子,其中 react 路由器仅用于维护 url 的哈希标记,并且也只更新一个组件。
【问题讨论】:
为什么要将这个状态保存在 store 中,而不是仅仅使用 React Router 作为 URL 参数的真实来源,并使用它在 mapStateToProps(state, ownProps) 中注入的 props ? 因为url参数只包含了讲座的slug和被选中的章节。在商店中,我有一个讲座和章节列表,其中包含名称、slug 和选定的布尔值。 例如使用peterbeshai.com/react-url-query ? 【参考方案1】:我认为你不需要。 (很抱歉给出了不屑一顾的答案,但这是我经验中最好的解决方案。)
存储是数据的真实来源。这很好。 如果你使用 React Router,让它成为你 URL 状态的真实来源。 您不必将所有东西都保留在商店中。
例如,考虑您的用例:
因为 url 参数只包含讲座的 slug 和选择的章节。在商店中,我有一个讲座和章节列表,其中包含名称、slug 和选定的布尔值。
问题是您正在复制数据。存储中的数据 (chapter.selected
) 在 React Router 状态下被复制。一种解决方案是同步它们,但这很快就会变得复杂。为什么不让 React Router 成为选定章节的真实来源?
您的商店状态将如下所示(简化):
// Might be paginated, kept inside a "book", etc:
visibleChapterSlugs: ['intro', 'wow', 'ending'],
// A simple ID dictionary:
chaptersBySlug:
'intro':
slug: 'intro',
title: 'Introduction'
,
'wow':
slug: 'wow',
title: 'All the things'
,
'ending':
slug: 'ending',
title: 'The End!'
就是这样!不要在那里存储selected
。而是让 React Router 处理它。在您的路由处理程序中,编写类似
function ChapterList( chapters )
return (
<div>
chapters.map(chapter => <Chapter chapter=chapter key=chapter.slug />)
</div>
)
const mapStateToProps = (state, ownProps) =>
// Use props injected by React Router:
const selectedSlugs = ownProps.params.selectedSlugs.split(';')
// Use both state and this information to generate final props:
const chapters = state.visibleChapterSlugs.map(slug =>
return Object.assign(
isSelected: selectedSlugs.indexOf(slug) > -1,
, state.chaptersBySlug[slug])
)
return chapters
export default connect(mapStateToProps)(ChapterList)
【讨论】:
很抱歉这么晚才回来,但我上周正在度假。我有一个问题。您描述了一种从 url 获取数据并呈现它的方法。您将如何使用新选择的章节更新网址? 我会在动作创建器中调用browserHistory.push()
(其中browserHistory
是从react-router
导入的)。我可能会使用 Redux Thunk 来明确它的副作用。我会在里面打电话给dispatch( ... ); browserHistory.push(...)
。
嘿,丹。感谢 Redux!我的我也把我的 2 美分放在这个话题上并提出一个问题。如果应用程序状态转换逻辑依赖于查询中的数据怎么办?这意味着减速器需要它,你不能只是在商店里摆脱它。
@AlexanderReshytko 由于这些数据来自“外部世界”,我会在必要时发出操作。这并不意味着您需要一个通用的“路由更改”操作(即使您发现它有用时可以调度它)。然后你的 reducer 就可以像往常一样使用这些信息了。
发送参数重新选择选择器有点别扭,所以能够从商店中获取当前的url参数非常有用。【参考方案2】:
react-router-redux
可以帮你注入url的东西来存储,所以每次hash标签改变时,也要存储。
【讨论】:
它只是给你位置,而不是解析的参数,所以它的用处有限,除非你可以手动重新实现 React Router 给你的东西。这是一个很好的解决方案,可以使存储与操作保持同步以便记录和重放用户会话,但对于不需要它的应用来说,它并不是那么有用。以上是关于如何同步 Redux 状态和 url 哈希标签参数的主要内容,如果未能解决你的问题,请参考以下文章
有没有办法先在选项卡之间同步 redux 存储状态,然后让每个选项卡控制自己的状态?
node.js 中的多人游戏架构 - 与 Redux 的状态管理和同步