Сделайте так, чтобы предупреждающее сообщение исчезло через x раз в функциональном компоненте React - PullRequest
1 голос
/ 26 апреля 2020

Я сделал компонент expire, который позволяет содержанию в нем исчезать через x секунд. Он работает с использованием состояния и setTimeout.

import React, { useEffect, useState } from 'react';

function Expire(props)
{
    const [isVisible, setIsVisible] = useState(true);

    useEffect(() =>
    {
        setTimer(props.delay);
    }, []);


    const setTimer = (delay) =>
    {
        setTimeout(() => setIsVisible(false), delay);
    };

    return (
        isVisible
            ? <div>{props.children}</div>
            : <span />
    );
}

export default Expire;

Я использую его так:

<Expire delay="5000">
    <Alert type={alertMsgState} size="col-md-10" />
</Expire>

Но проблема, с которой я столкнулся, заключается в том, что после исчезновения один раз через 5 секунд, когда снова alertMsgState изменено [например, форма отправляется снова, поэтому я хочу снова показать предупреждение], сообщение не перерисовывается и исчезает через 5 секунд, как и должно быть. При осмотре я просто вижу элемент <span />.

Пожалуйста, ответьте, используя только функциональные компоненты и крючки.

Ответы [ 2 ]

1 голос
/ 26 апреля 2020

Вы не делаете ничего, что могло бы снова вызвать показ компонента оповещения.

Одним из решений является, например, использование целочисленной клавиши, а когда вы хотите показать ее снова, сделайте что-то вроде:

// inside parent
const [key, setKey] = useState(0);

// Say from a click handler when you again want to show your component, do:
let onClick=()=>{
  setKey(key+1);
}

//...

<Expire delay="5000" key={key}>
    <Alert type={alertMsgState} size="col-md-10" />
</Expire>

Когда между разными рендерами реагирует, встречает ваш компонент с разными ключами, он размонтирует старый компонент и монтирует его снова - следовательно, вы получите желаемое поведение.

0 голосов
/ 26 апреля 2020

Одна вещь, которую вы можете сделать, это связать useEffect с props.children, поэтому при каждом изменении вы сбрасываете сообщение, восстанавливаете видимость и снова запускаете тайм-аут:

function Expire(props)
{
    const [isVisible, setIsVisible] = useState(true);
    const [children, setChildren] = useState(props.children)

    useEffect(() =>
    {
        setChildren(props.children)
        setIsVisible(true)
        setTimer(props.delay);
    }, [props.children]);


    const setTimer = (delay) =>
    {
        setTimeout(() => setIsVisible(false), delay);
    };

    return (
        isVisible
            ? <div>{children}</div>
            : <span />
    );
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...