How to synchronize Redux and Relay?

Situation

I have an onboarding script where a user goes through a step-by-step inclusion. I want to manage the client state of user progress using Redux. Synchronization between the server and the client is already implemented in Relay, but I still need Redux storage to manage client-side state. Thus, there are problems with the synchronization of the repeater / gearbox.

What I'm doing right now is to wrap my React component using Redux and then using 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 ...
      }
    `,
  },
})  

My progress

I found ways to perform various operations as follows:

Initializing Redux Storage with Server Data

Redux Relay. , redux-thunk. Redux Relay, . ( , " " ): 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'))
        }
      })
    })
  }
}

Redux

Redux => Relay => Server

, onboarding, 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}
}

:

Redux

, . Relay forceFetching . Relay : Relay <= Server. : Relay => Redux .

Redux - , Relay .

, . , , .

Redux, Redux, Relay . .

:

  • ? -, , / ? (. )
  • Redux, - . React Relay, Redux Redux. (. )
+4
1

RelayNetworkLayer - , , , , . , - .

+1

Source: https://habr.com/ru/post/1648283/


All Articles