Empresas
Empleos
  • Sobre nosotros
  • Soluciones
    • Publicación de vacantes
      Publica tu vacante y recibe candidatos calificados en 48h.
    • Evaluación de candidatos
      500+ pruebas técnicas y psicológicas, más anti-fraude.
    • Headhunting
      Búsqueda ejecutiva a la medida de principio a fin.
    • Nómina + EOR
      Dispersión de nómina y EOR en más de 15 países de LATAM.
  • Precios
  • Empleos

0

181
Vistas
How to make a child React component show for a certain amount of time?

I have a React component called PopUpBanner that I use to show messages. For example, in my login component, I use it like this. If an error occurs, then I set the bannerMessage state to have text so that the banner shows:

        this.setState({
          bannerMessage: {
            msg: error.message + ". Incorrect email address or password.",
            isError: true,
          },
        });

Here is how the component is then used:

<PopUpBanner
    message={bannerMessage.msg}
    isError={bannerMessage.isError}
></PopUpBanner>

And here is the PopUpBanner class:

import React, { Component } from "react";

class PopUpBanner extends Component {
  constructor(props) {
    super(props);
    this.state = {
      message: this.props.message,
    };
  }

  // TODO : not in use
  reset = () => {
    this.resetId = setTimeout(
      function () {
        this.setState({ message: "" });
      }.bind(this),
      3000
    );
  };

  componentDidMount() {}

  componentWillUnmount() {
    if (this.timeoutId) {
      clearTimeout(this.timeoutId);
      console.log("clearing time out");
    }
  }

  render() {
    const message = this.props.message;
    const isError = this.props.isError;
    return (
      <div style={message != "" ? { display: "block" } : { display: "none" }}>
        <div>
          {isError ? (
            <div
              className="alert alert-danger text-center"
              role="alert"
              style={{ width: "50%", margin: "auto" }}
            >
              {message}
            </div>
          ) : (
            <div
              className="alert alert-primary text-center"
              role="alert"
              style={{ width: "50%", margin: "auto" }}
            >
              {message}
            </div>
          )}
        </div>
      </div>
    );
  }
}

export default PopUpBanner;

The problem is that the PopUpBanner is shown until the page is refreshed or navigated to another page.

So if you look at the PopUpBanner class, I attempted to use setTimeout but wasn't able to finish it.

Any ideas on how I can transform PopUpBanner component to be on a timer?

about 4 years ago · Juan Pablo Isaza
1 Respuestas
Responde la pregunta

0

I see two options:

  1. Handle it in the parent component, only rendering PopUpBanner when it should be there, using setTimeout to trigger a state update that re-renders the parent without rendering PopUpBanner.

  2. Handle it in PopUpBanner, returning null from render after the expiration.

I would prefer #1 over #2. But your existing code is basically doing #2, you just have to adjust render to support it:

render() {
    const message = this.props.message;
    if (!message) {
        return null;
    }
    // ...show the message...

But as discussed in teh comments, I wouldn't copy props to state like that. So instead:

constructor(props) {
    super(props);
    this.state = {
        expiredMessage: null,
    };
}

then to expire a message:

setupExpiration() {
    this.expirationTimer = setTimeout(() => {
        this.setState(() => ({expiredMessage: this.props.message}));
    }, 1000); // <== Or however long you want it showing
}

...which you call from a couple of lifecycle methods:

componentDidMount() {
    this.setupExpiration();
}
componentDidUpdate() {
    this.setupExpiration();
}

and render becomes:

render() {
    const { expiredMessage } = this.state;
    const { message } = this.props;
    if (expiredMessage === message) {
        return null;
    }
    // ...show the message...

But again, I'd go for having the parent in control of this, actually removing PopUpBanner when it shouldn't be showing:

class PopUpBanner extends React.Component {
    render() {
        const {message} = this.props;
        return <div className="banner">{message}</div>;
    }
}

class Parent extends React.Component {
    state = {
        message: null,
    };

    constructor(props) {
        super(props);
        this.showMessage = this.showMessage.bind(this);
        this.messageTimer = 0;
    }

    showMessage() {
        clearTimeout(this.messageTimer);
        this.setState({message: "Hi there, I'm a banner"});
        this.messageTimer = setTimeout(() => {
            this.setState({message: null});
        }, 1000);
    }

    render() {
        const {message} = this.state;
        const {showMessage} = this;
        return <div className="with-banner">
            {message && <PopUpBanner message={message} />}
            <div>
                <input type="button" value="Show Message" onClick={showMessage} />
            </div>
        </div>;
    }
};

ReactDOM.render(<Parent />, document.getElementById("root"));
<div id="root"></div>

<script src="https://cdnjs.cloudflare.com/ajax/libs/react/17.0.2/umd/react.development.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/17.0.2/umd/react-dom.development.js"></script>

about 4 years ago · Juan Pablo Isaza Denunciar
Responde la pregunta
Encuentra empleos remotos

¡Descubre la nueva forma de encontrar empleo!

Top de empleos
Top categorías de empleo
Empresas
Publicar vacante Precios Comercial
Legal
Términos y condiciones Política de privacidad
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomiéndame algunas ofertas
Necesito ayuda