0

Have a ReactJS + Redux + Saga application that was recently updated to use the latest (or close to latest) versions of the respective JS libraries. After the library updates (no code changes) and running the application, I immediately see the "Cannot update during an existing state transition (such as within render). Render methods should be a pure function of props and state." warning message in the console. It looks to be triggered by redux when I invoke the dispatch function (which then calls a function in Provider.js, then goes through react-dom, and then in turn writes the warning message. Again nothing in my code has changed, and my code is essentially built using stateless functions.

Not sure how to go about figuring out what is causing this warning-- although the app still runs ok as expected. Using React 16.8.6, react-redux 6.0.1, react-router-dom 5.0.0, redux 4.0.1, redux-saga 1.0.2, and connected-react-router 6.4.0.

Below is a sample page that would cause the warning message:

import React from 'react'
import {connect} from 'react-redux'
import {links} from '../links'
import {notify} from '../notifications'

const Home = props => {
    const {dispatch} = props

    return (
        <main>          
            <p>
                <a href={links.DETAILS} onClick={() => {dispatch(notify(links.DETAILS))}} target="_blank">Go to Details</a>...
            </p>
        </main>
    )}
const dispatcher = dispatch => {
    dispatch(notify(links.HOME))

    return {dispatch}
}
export default connect(null, dispatcher)(Home)      
Los Morales
  • 2,061
  • 7
  • 26
  • 42
  • 1
    Mind sharing the part of the code that causes this warning, it might be insightful for diagnosis. – Tomer Apr 22 '19 at 04:54
  • Ok just posted a page that would display that warning message. Looks to happen in the dispatcher function. – Los Morales Apr 22 '19 at 13:05

1 Answers1

1

You cannot call to dispatch inside the disaptcher function.

react-redux's connect parameters are:

function connect(mapStateToProps?, mapDispatchToProps?, mergeProps?, options?)

mapDispatchToProps is what you called dispatch. These params are eventually run as functions that called in the render loop of the connected component. When you dispatch in the render loop it changes the state of a React component (looks like it's the Provider), which is forbidden by React.

Solution Move the dispatch(notify(links.HOME)) to lifecycle method. For example you can add to the Home component (this will require to rewrite the Home component as an extension of React.Component class:

componentDidMount() {
  dispatch(notify(links.HOME))
}

UPDATE

If you want to do this with classless component see that question

leonprou
  • 4,638
  • 3
  • 21
  • 27
  • Thanks for the response. Is there a way to do this without extending from React Component? As I mentioned, all our code comprises of stateless functions-- we don't extend from Component. Maybe there is another way to do this? The purpose of doing calling notify() is really only on page entrance. When a user hits the Home page, we want send a notification. Any way of doing all of this without creating a class that extends Component? – Los Morales Apr 23 '19 at 12:58