eugene
eugene

Reputation: 41665

React, redux, dispatch action during render

I'm rendering different components on condition

  render() {

    switch(foo) {
    case 'a': return <A/>
    case 'b': return <B/>
    default: return <C/>
    }
  }

Now I want to track how many times each screen is visited, and do something like following

render() {

  switch(foo) {
  case 'a':
    this.props.dispatch(analytics.log({"screen": "A"}))
    return <A/>
  case 'b':
    this.props.dispatch(analytics.log({"screen": "B"}))
    return <B/>
  default:
    this.props.dispatch(analytics.log({"screen": "C"}))

    return <C/>

}

I'm getting an error cannot update during an existing state transition (such as withinrender). Render methods should be a pure function of props and state.

I can't move the logging function call to componentDidMount because users move these screens like tab .

In this, case render is the perfect place to put the log, but react suggest me not to.

What can I do?

Upvotes: 1

Views: 4251

Answers (3)

Oliver
Oliver

Reputation: 237

I would wrap this into the onClick handler for each component.

e.g:

onClick = ('A'/'B'/'C') => {
    dispatch(analytics.log('A');
    history.push('A') or switch tab to ('A') // however you are handling tab change.
} 

alternatively you could move the dispatch into the children components so when they are rendered, you dispatch the action there.

in :

useEffect(() => { // or componentDidMount
 dispatch(analytics.log('A')
}, []) 

 // rest of A component.

Upvotes: 0

Sagiv b.g
Sagiv b.g

Reputation: 31014

I assume you can't move this logic to componentDidMount because they all render at the same time (you mentioned Tabs), then i would move it to the onClick handler of the buttons that switch the tabs.

Upvotes: 2

noodles_ftw
noodles_ftw

Reputation: 1313

Move the dispatch into the componentDidMount of your components <A />, <B /> and <C />.

Upvotes: 1

Related Questions