Is it possible to connect non component Class to redux store?

11,941

The connect function is not going to work with anything other than React components. What you can do is pass your store instance to your class and call store.dispatch, store.getState, and store.subscribe directly.

Keep in mind that if you subscribe, you should also have functionality to unsubscribe, otherwise your store will be holding a reference to your class instance forever, creating a memory leak.

Share:
11,941

Related videos on Youtube

j_d
Author by

j_d

Updated on June 04, 2022

Comments

  • j_d
    j_d almost 2 years

    So I am using a react-redux boilerplate that has an ApiClient helper. It looks like this:

    export default class ApiClient {
      constructor(req) {
        /* eslint-disable no-return-assign */
        methods.forEach((method) =>
          this[method] = (path, withCredentials, { params, data } = {}) => new Promise((resolve, reject) => {
    
            const request = superagent[method](formatUrl(path))
    
            if (withCredentials) {
              console.log('first of all, its true')
              console.log(this)
            }
    
            if (params) {
              request.query(params)
            }
    
            if (__SERVER__ && req.get('cookie')) {
              request.set('cookie', req.get('cookie'))
            }
    
            if (data) {
              request.send(data)
            }
    
            request.end((err, { body } = {}) => {
    
              return err ? reject(body || err) : resolve(body)
    
            })
          }))
        /* eslint-enable no-return-assign */
      }
      /*
       * There's a V8 bug where, when using Babel, exporting classes with only
       * constructors sometimes fails. Until it's patched, this is a solution to
       * "ApiClient is not defined" from issue #14.
       * https://github.com/erikras/react-redux-universal-hot-example/issues/14
       *
       * Relevant Babel bug (but they claim it's V8): https://phabricator.babeljs.io/T2455
       *
       * Remove it at your own risk.
       */
      empty() {}
    }
    

    I want to connect this to my auth so that I can prepend headers to protected endpoints, like so:

    @connect(state => ({ jwt: state.auth.jwt }))
    export default class ApiClient {
      ...
    

    However, when I do this, I get the error: Cannot read property 'store' of undefined. What's going on here? Why can't I connect a regular Class to the redux store?

    Update: here's my login function, which uses the ApiClient helper:

    export function loginAndGetFullInto(email, password) {
      return dispatch => {
        return dispatch(login(email, password))
        .then(() => {
          return dispatch(loadUserWithAuth())
        })
      }
    }
    

    I need some way to either pass the store, or the jwt, into the loadUserWithAuth function...

  • ArcadeRenegade
    ArcadeRenegade about 7 years
    i did not realize i could call the store constant directly. this is perfect for my app component as I was not able do a traditional connect with the app component without causing my flux router to rerender.
  • Darren Lau
    Darren Lau over 5 years
    @ArcadeRenegade do you mind to show me how you do it?