<commit_before>import * as React from 'react';
import ToastText from './ToastText';
import classNames from 'classnames';

export type MessageProp =
    | React.ReactNode
    | string;

export type Position = 'top' | 'bottom' | 'top-right' | 'top-left' | 'bottom-right' | 'bottom-left';

export type NotesType = 'default' | 'primary' | 'success' | 'warning' | 'alert' | 'highlight' | 'light';

export interface IMessageOptions {
    message?: MessageProp;
    id?: string;
    duration?: number | null;
    type?: NotesType;
    position?: Position;
    icon?: string;
    size?: 'fixed-s' | 'fixed-m' | 'fixed-l' | 'fixed-xl';
}

interface IProps extends IMessageOptions {
    closeElement(id: string, position: Position): void;
}

export const ToastMessage = ({
    id,
    message,
    type,
    icon,
    size,
    duration,
    position,
    closeElement,
}: IProps) => {
    const [show, setShow] = React.useState();
    const [enter, setEnter] = React.useState(true);
    let timer = null;

    React.useEffect(() => {
        if (show === undefined) {
            setShow(true);
        }
        if (typeof duration === "number") {
            setEnter(true);
            timer = setTimeout(() => {
                close(id, position);
            }, duration);
            return () => clearTimeout(timer);
        }
    }, [enter]);

    function onMouseEnter() {
        clearTimeout(timer);
    }

    function onMouseLeave() {
        setEnter(false);
    }

    function close(element: string, elementPosition: Position) {
        setShow(false);
        setTimeout(() => {
            closeElement(element, elementPosition);
        }, 150);
    }
    const classes = classNames('sd-toast', {
        [`sd-toast--${type}`]: type,
        [`sd-toast--${size}`]: size,
        ['sd-toast--enter']: show === undefined,
        ['sd-toast--enter-active']: show,
        ['sd-toast--exit']: enter && !show,
        ['sd-toast--exit-active']: !show,
    });

    return (
        <div
            className={classes}
            onMouseEnter={onMouseEnter}
            onMouseLeave={onMouseLeave}
        >
            <ToastText id={id} title={message} icon={icon} onClose={() => close(id, position)} />
        </div>
    );
};
<commit_msg>react(feat): fixed using single useeffect<commit_after>import * as React from 'react';
import ToastText from './ToastText';
import classNames from 'classnames';

export type MessageProp =
    | React.ReactNode
    | string;

export type Position = 'top' | 'bottom' | 'top-right' | 'top-left' | 'bottom-right' | 'bottom-left';

export type NotesType = 'default' | 'primary' | 'success' | 'warning' | 'alert' | 'highlight' | 'light';

export interface IMessageOptions {
    message?: MessageProp;
    id?: string;
    duration?: number | null;
    type?: NotesType;
    position?: Position;
    icon?: string;
    size?: 'fixed-s' | 'fixed-m' | 'fixed-l' | 'fixed-xl';
}

interface IProps extends IMessageOptions {
    closeElement(id: string, position: Position): void;
}

export const ToastMessage = ({
    id,
    message,
    type,
    icon,
    size,
    duration,
    position,
    closeElement,
}: IProps) => {
    const [show, setShow] = React.useState();
    const [enter, setEnter] = React.useState(true);
    let timer = null;

    React.useEffect(() => setShow(true), []);

    React.useEffect(() => {
        if (typeof duration === "number") {
            setEnter(true);
            timer = setTimeout(() => {
                close(id, position);
            }, duration);
            return () => clearTimeout(timer);
        }
    }, [enter]);

    function onMouseEnter() {
        clearTimeout(timer);
    }

    function onMouseLeave() {
        setEnter(false);
    }

    function close(element: string, elementPosition: Position) {
        setShow(false);
        setTimeout(() => {
            closeElement(element, elementPosition);
        }, 150);
    }
    const classes = classNames('sd-toast', {
        [`sd-toast--${type}`]: type,
        [`sd-toast--${size}`]: size,
        ['sd-toast--enter']: show === undefined,
        ['sd-toast--enter-active']: show,
        ['sd-toast--exit']: enter && !show,
        ['sd-toast--exit-active']: !show,
    });

    return (
        <div
            className={classes}
            onMouseEnter={onMouseEnter}
            onMouseLeave={onMouseLeave}
        >
            <ToastText id={id} title={message} icon={icon} onClose={() => close(id, position)} />
        </div>
    );
};

{'fraction_non_alphanumeric': 0.16245006657789615, 'fraction_numerical': 0.0013315579227696406, 'mean_word_length': 2.353422619047619, 'pattern_counts': {'":': 0, '<': 9, '<?xml version=': 0, '>': 22, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '6876600', 'n_tokens_mistral': 1366, 'n_tokens_neox': 1359, 'n_words': 310}