question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

kea combined with react-redux `connect` --> no kea sagas run

See original GitHub issue

I found this while trying out kea in an existing app. I have a HOC that uses connect from react-redux. Long story short, you can’t call kea({...options})(MyComponent) if MyComponent has already had connect (from react-redux) called on it.

If you do this and call the actions defined in your kea options, the actions will fire but the corresponding sagas will not run.

More (too much?) detail:

export default function HOC(callback, mapStateToProps, mapDispatchToProps) {
  return function factory(WrappedComponent) {
    class Wrapper extends PureComponent {
      componentDidMount() {
        callback(this.props);
      }
      render() {
        return <WrappedComponent {...this.props} />
      }
    }

    return connect(mapStateToProps, mapDispatchToProps)(Wrapper);
  }
}

// in another file...
const Logic = kea({
    actions: () => ({
        greet: person => ({person}),
    }),
    workers: {
        handleGreeting: function* (action) {
            yield call(hello, action.payload.person);
            // etc...
        },
    },
    takeEvery: ({actions, workers}) => ({
      [actions.greet]: workers.handleGreeting,
    }),
});

const SillyComponent = props => (<div>Sent a greeting to {props.person}</div>);
// dispatch api call on mount...
const callback = (props) => props.actions.hello(props.person);

export default Logic(HOC(callback)(SillyComponent))

If you use <SillyComponent person="Bob"/> somewhere, it will dispatch the action when it mounts, but workers.handleGreeting will never run.

Issue Analytics

  • State:closed
  • Created 6 years ago
  • Comments:5 (5 by maintainers)

github_iconTop GitHub Comments

5reactions
mariusandracommented, Aug 22, 2017

Hey, sorry for the radio silence. I’ve been in the hospital for the last 6 days - my daughter was born on Friday (everything is ok!), so I had no time to check this 😃.

I’ll reply later today or in the worst case in the next days.

0reactions
mariusandracommented, Aug 25, 2017

Hey, the sagas are already running in the wrapped component’s componentDidMount, just that in your case you wanted them before this lifecycle method: in your wrapped component’s wrapped component’s componentDidMount 😃.

The following code works fine:

import React, { Component } from 'react'
import { kea } from 'kea'
import PropTypes from 'prop-types'

@kea({
  actions: () => ({
    showAlert: (id) => ({ id }),
    hideAlert: (id) => ({ id })
  }),
  reducers: ({ actions }) => ({
    visibleAlerts: [{}, PropTypes.object, {
      [actions.showAlert]: (state, payload) => ({ ...state, [payload.id]: true }),
      [actions.hideAlert]: (state, payload) => ({ ...state, [payload.id]: false })
    }]
  }),
  takeEvery: ({ actions }) => ({
    [actions.showAlert]: function * () {
      console.log('showAlert called')
    }
  })
})
export default class App extends Component {
  componentDidMount () {
    const { showAlert } = this.actions
    console.log('mounted')
    showAlert('Alert1')
  }

  render () {
    const { showAlert } = this.actions
    const { visibleAlerts } = this.props

    return (
      <div>
        {visibleAlerts.Alert1 ? 'alert1 visible' : ''}
        <button onClick={() => showAlert('Alert1')} disabled={visibleAlerts.Alert1}>Show Alert1</button>
        <br />
        {visibleAlerts.Alert2 ? 'alert2 visible' : ''}
        <button onClick={() => showAlert('Alert2')} disabled={visibleAlerts.Alert2}>Show Alert2</button>
      </div>
    )
  }
}

When I open the page, Alert1 is visible.

I have added a note to the docs a note about this (api -> start/stop/takeEvery/takeLatest).

Your case was indeed kind of special, and I’d prefer not to complicate the library too much. Let’s see if this is a common issue people run into.

Glad to hear that you found a workaround for it 😃.

Read more comments on GitHub >

github_iconTop Results From Across the Web

Kea - High level abstraction between React and Redux
Kea is an extremely smart mountain parrot from New Zealand. Kea is also an extremely smart abstraction between React, Redux, Redux-Saga and ...
Read more >
Connect react with redux, redux-saga | by Amitha Mahesh
We need to install redux, react-redux, redux-saga if we wish to use it as a asynchronous middleware.
Read more >
Composable state management for React | Kea 3.0
Kea is a production-grade state management framework built for ambitious React apps.
Read more >
Step-By-Step: How to Add Redux Saga to a React & Redux App
Step 5: Apply the saga middleware to redux​​ Using the utility function applyMiddleware we can combine multiple middlewares and return a single ...
Read more >
How to use the react-redux.connectAdvanced function ... - Snyk
Secure your code as it's written. Use Snyk Code to scan source code in minutes - no build needed - and fix issues...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found