gpt4 book ai didi

reactjs - 如何同步Redux和Relay?

转载 作者:行者123 更新时间:2023-12-03 13:38:29 29 4
gpt4 key购买 nike

情况

我有一个新手入门场景,用户可以在其中逐步入门。我想使用 Redux 管理用户进度的客户端状态。服务器和客户端之间的同步已经在 Relay 中实现,但我仍然需要一个 Redux 存储来进行客户端状态管理。因此,同步 Relay-/Redux-Store 时会出现问题。

我现在正在做的是用 Redux 包装我的 React 组件,然后用 Relay 包装:

// OnboardProgressView.js
// ...

// wrap React component with Redux
const mapStateToProps = (state) => {
return {
onboardProgress: state.onboardProgress,
}
}

const ReduxContainer = connect(
mapStateToProps,
)(OnboardProgressView)

// this is only for convenience of access of the Relay data
const MappedOnboardProgressView = mapProps({
params: (props) => props.params,
user: (props) => props.viewer.user,
})(ReduxContainer)

// wrap Redux component with Relay
export default Relay.createContainer(MappedGettingStartedView, {
fragments: {
viewer: () => Relay.QL`
fragment on Viewer {
user {
userId
onboardProgressStep
}
# more stuff ...
}
`,
},
})

我的进度

我找到了完成不同操作的方法,如下所示:

使用服务器数据初始化 Redux 存储

我在使用异步原始中继查询创建存储后立即初始化 Redux 状态。为了实现这一点,我还使用 redux-thunk中间件。 Redux 向 Relay 发起请求,查询服务器。视觉表示(箭头表示数据流,元素的顺序反射(reflect)“​​调用顺序”):Redux <= Relay <= Server

// app.js
const store = createStore(reducer, applyMiddleware(thunk))
store.dispatch(fetchOnboardProgress())

// onboardProgress.js
export function fetchOnboardProgress () {
return function (dispatch) {
var query = Relay.createQuery(Relay.QL`
query {
viewer {
user {
id
onboardProgress
}
}
}`, {})

return new Promise(function (resolve, reject) {
Relay.Store.primeCache({query}, ({done, error}) => {
if (done) {
const data = Relay.Store.readQuery(query)[0]
dispatch(update(data.user.onboardProgress, data.user.id))
resolve()
} else if (error) {
reject(Error('Error when fetching onboardProgress'))
}
})
})
}
}

分派(dispatch) Redux 操作时更新服务器上的数据

Redux => Relay => Server

为了获得一致的状态更改,当用户完成入职流程时,我会触发一个 Redux 操作,该操作也会异步执行 Relay 突变。我也在使用redux-thunk为此目的。

function nextStep () {
return function (dispatch, getState) {
const currentStep = getState().onboardProgress.step
const currentStepIndex = OnboardProgress.steps.indexOf(currentStep)
const nextStep = OnboardProgress.steps[currentStepIndex + 1]
const userId = getState().onboardProgress._userId

return _updateReduxAndRelay(dispatch, nextStep, userId)
}
}

function _updateReduxAndRelay (dispatch, step, userId) {
return new Promise((resolve, reject) => {
Relay.Store.commitUpdate(new UpdateUserMutation({
userId: userId,
onboardProgressStep: step,
}), {
onSuccess: () => {
dispatch(update(step, userId))
resolve()
},
onFailure: reject,
})
})
}

export function update (step, userId) {
const payload = {onboardProgress: new OnboardProgress({step, userId})}
return {type: UPDATE, payload}
}

Unresolved 问题

我仍然没有找到解决以下情况的方法:

当 Relay Store 更新时更新 Redux Store

服务器上数据的更改可能有外部来源,这些来源不是由我们应用中的用户操作触发的。使用 Relay,我们可以通过强制获取或轮询来解决这个问题。中继查询如下所示:Relay <= Server 。我还想有这个数据流:Relay => Redux当外部数据发生变化时。

需要用新数据更新 Redux 存储的另一个可能原因是当我们想要同步深度嵌套在 Relay 存储中的数据或复杂查询的一部分时。

例如,考虑博客文章的评论数量。当用户发布新评论时,显示评论计数的另一个组件也应该更新。

如果我们在 Redux 中管理这些信息,我们需要一种方法来在 Relay 查询带来新信息时触发 Redux 操作。我不知道有这样的回调,或者这种情况的其他解决方案。

我的问题

在这种情况下,我有这些问题:

  1. 我可以对现有方法进行哪些改进?我所做的事情是否非常危险/导致不一致? (参见我的进展)
  2. 由于某种原因更新 Relay 存储时,如何同步 Redux 存储。我正在寻找 React 组件生命周期方法或 Relay 回调,然后我可以将 Redux 操作发送到 Redux 存储。 (请参阅未决问题)

最佳答案

RelayNetworkLayer您应该使用它来将 redux 存储与中继存储同步,因为它允许您订阅那里发生的所有事情。如果有其他想法,我稍后会更新这篇文章。

关于reactjs - 如何同步Redux和Relay?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38443093/

29 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com