<div id="root"></div>
body {
  margin: 0;
  padding: 0;
}


.cat__img {
  transition-property: left, top;
  transition-duration: 0.5s, 0.5s;
  transition-timing-function: ease, ease;
}
class Animal extends React.Component {
  constructor (props) {
    super(props);
    this.state = {
      src: props.src
    }
    console.log('/*** constructor(props) ***/');
  }
  
  static getDerivedStateFromProps (nextProps, prevState) {
    console.log('/*** getDerivedStateFromProps(nextProps, prevState) ***/');    
    if (prevState.src !== nextProps.src) {
      // necesario para actualizar la imagen cada vez que cambie this.props.src
      return { src: nextProps.src };
    }
    
    return null;
  }
  
  
  render() {
    console.log('/*** render() ***/');      
    return (
        <img className="cat__img"
          src={this.state.src}
          />
     );
   }

   componentDidMount () {
    console.log('/*** componentDidMount() ***/');
    console.log('----------------------------------');
   }
    
   // Se ejecuta solo hasta que hay un cambio de state o props,
   // pero no se ejecuta en el primer render
   shouldComponentUpdate(nextProps, nextState) {
      console.log('/*** shouldComponentUpdate(nextProps, nextState) ***/');
      return true;
    }

    getSnapshotBeforeUpdate(prevProps, prevState) {
      console.log('/*** getSnapshotBeforeUpdate(prevProps, prevState) ***/');
      return null;
    }

    componentDidUpdate(prevProps, prevState, snapshot) {
      console.log('/*** componentDidUpdate(prevProps, prevState, snapshot) ***/');
      console.log('----------------------------------');
    }

}



class Padre extends React.Component {
  constructor(props) {
    super(props);
    this.animales = [
      'https://i.pinimg.com/236x/b2/cb/7d/b2cb7d5630eb5e5a60ed8f3e1d58e680--best-dog-food-best-dogs.jpg',
      'https://pa1.narvii.com/5816/867e0deb7c7a4b651c37b9d6164c755d1cce6d6e_128.gif',
      'https://pbs.twimg.com/profile_images/742621666027569152/m345-jkv_400x400.jpg',
      'https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcRFxEoBS0Dlue23lz4MxyuuK0GXZwNvdueWbCLZFXwuM_xjIhhC',
      'https://is5-ssl.mzstatic.com/image/thumb/Purple122/v4/e2/e5/40/e2e5408c-ea6a-042f-78a0-38fca8534133/source/256x256bb.jpg'
    ]; 
    this.animalIndex = 0;
    this.state = { src: this.animales[this.animalIndex] };
  }


  cambiarAnimal = () => {
    this.animalIndex++;
    let animalSrc = this.animales[this.animalIndex]
    
    if (!animalSrc) {
      this.animalIndex = 0;
      animalSrc = this.animales[this.animalIndex]
    }

    this.setState({
      src: animalSrc
    });
  };
  
  render() {
    return (
      <div>
        <Animal src={this.state.src}/>
        <button onClick={this.cambiarAnimal}>Cambiar animal</button>
      </div>
    );
  }
}

ReactDOM.render(<Padre  />, document.getElementById('root'));
View Compiled

External CSS

This Pen doesn't use any external CSS resources.

External JavaScript

  1. https://cdnjs.cloudflare.com/ajax/libs/react/16.3.0/umd/react.development.js
  2. https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.3.0/umd/react-dom.development.js