Bai Chan Kheo
Bai Chan Kheo

Reputation: 413

componentDidUpdate is not firing

Is componentDidUpdate suppose to fire when I change routes using react-router? I modified the example code and can't seem to get it to work.

I made the home component log some text but it isn't firing it seems. Any help is appreciated, thanks!

Code:

import React from 'react';
import ReactDOM from 'react-dom';
import App from './App';
import './index.css';
import {
    BrowserRouter as Router,
    Route,
    Link
} from 'react-router-dom'

const BasicExample = () => (
    <Router>
        <div>
            <ul>
                <li><Link to="/">Home</Link></li>
                <li><Link to="/about">About</Link></li>
                <li><Link to="/topics">Topics</Link></li>
            </ul>

            <hr/>

            <Route exact path="/" component={Home}/>
            <Route path="/about" component={About}/>
            <Route path="/topics" component={Topics}/>
        </div>
    </Router>
)

class Home extends React.Component {
    render() {
        return (<div>
            <h2>Home</h2>
        </div>);
    }

    componentDidUpdate() {
        console.log("Updated!");
    }
}


const About = () => (
    <div>
        <h2>About</h2>
    </div>
)

const Topics = ({ match }) => (
    <div>
        <h2>Topics</h2>
        <ul>
            <li>
                <Link to={`${match.url}/rendering`}>
                    Rendering with React
                </Link>
            </li>
            <li>
                <Link to={`${match.url}/components`}>
                    Components
                </Link>
            </li>
            <li>
                <Link to={`${match.url}/props-v-state`}>
                    Props v. State
                </Link>
            </li>
        </ul>

        <Route path={`${match.url}/:topicId`} component={Topic}/>
        <Route exact path={match.url} render={() => (
            <h3>Please select a topic.</h3>
        )}/>
    </div>
)

const Topic = ({ match }) => (
    <div>
        <h3>{match.params.topicId}</h3>
    </div>
)

ReactDOM.render(
  <BasicExample />,
  document.getElementById('root')
);

Upvotes: 29

Views: 42963

Answers (2)

Immobilus
Immobilus

Reputation: 101

Slight recommended change: Passing objects into setState methods is deprecated. Use the prevState property and flip its value.

class Home extends React.Component {

        constructor(){
            super();
            this.state = {a: false}
        }

        componentDidUpdate() {
            console.log("Updated!");
        }

        render() {
            return (
                <div>
                   <h2>Home</h2>
                   <p onClick={()=>this.setState((prevState) => ({a: !prevState.a}))}>Click Me</p>
                </div>
            );
        }
    }


    ReactDOM.render(<Home/>, document.getElementById('app'))

Upvotes: -2

Mayank Shukla
Mayank Shukla

Reputation: 104379

As per the DOC:

An update can be caused by changes to props or state. These methods are called when a component is being re-rendered:

componentWillReceiveProps()

shouldComponentUpdate()

componentWillUpdate()

render()

componentDidUpdate()

componentWillUpdate:

componentWillUpdate() is invoked immediately before rendering when new props or state are being received. Use this as an opportunity to perform preparation before an update occurs. This method is not called for the initial render.

In Home component you didn't define any state and you are not using any propsalso, that't why that function will not get called.

Check this example componentDidUpdate will get called when you click on Click Me text:

class Home extends React.Component {
    
    constructor(){
        super();
        this.state = {a: false}
    }

    componentDidUpdate() {
        console.log("Updated!");
    }
    
    render() {
        return (
            <div>
               <h2>Home</h2>
               <p onClick={()=>this.setState({a: !this.state.a})}>Click Me</p>
            </div>
        );
    }
}


ReactDOM.render(<Home/>, document.getElementById('app'))
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>

<div id='app'/>

Upvotes: 10

Related Questions