简体   繁体   中英

How can I map through Props consisting of 3 useMemo functions in React?

I have 3 separate functions using useMemo that return a different type of alert for a user in a dashboard.

These alerts appear at the top of the user dashboard if they are truthy, but if there is more than 1 alert that should appear, they are placed within a slideshow that slides automatically.

I have created a Slideshow component and pass all 3 functions in through props. My question is how I can map through props in the Slideshow component to render out these alerts?

I have tried to do so with 'props.map' but receive an error about map missing from PropTypes so am unsure if I am doing this correctly by trying to render out the alerts with a.map?

This is my main file with the 3 useMemo alerts:

export const TransactionsPage = (props) => {
    const { t } = props;
    const { data: profile } = apiService.useGetSingleAccountQuery();
    const { data: accountInfo } = apiService.useGetPlanQuery();

 const renderMaxManualTransactionWarning = useMemo(() => {
        if (accountInfo?.exceed_tx_capability)
        return (
            <>
                <div className={"free-trial-info"}>
                    <div className={"row"}>
                        <CryptoIcon name={"alert"} />
                        <Text size={14}>{t("pages.transactions.warning.transactions_limit")}</Text>
                    </div>
                    <Button
                        size={"small"}
                        type={"primary"}
                        onClick={() => historyObject.push("/account/subscription/change_plan")}
                    >
                        {t("pages.transactions.warning.action")}
                        <CryptoIcon name={"arrow-right"} />
                    </Button>
                </div>
            </>
        );
        }, [t, accountInfo]);
    // }, [t]);

    const renderMissingTransferTransactionWarning = useMemo(() => {
        if (unlinkedTransferTx?.items?.length > 0)
            return (
                <>
                    <div className={"import-warning"}>
                        <div className={"row"}>
                            <CryptoIcon name={"alert"} />
                            <Text size={14}>
                                {t("pages.transactions.warning.transfer_transactions_missing").replace(
                                    "[num]",
                                    unlinkedTransferTx.items.length
                                )}
                            </Text>
                        </div>
                        <Button
                            size={"small"}
                            type={"primary"}
                            onClick={() => historyObject.push("/transactions/transfer/list")}
                        >
                            {t("pages.transactions.warning.transfer_transactions_missing_action")}
                            <CryptoIcon name={"arrow-right"} />
                        </Button>
                    </div>
                </>
            );
    }, [t, unlinkedTransferTx]);

    const renderSuggestedLinksWarning = useMemo(() => {
        if (suggestedLinks?.items?.length > 0)
            return (
                <div className={"suggested-links-info"}>
                    <div className={"row"}>
                        <CryptoIcon name={"alert"} />
                        <Text size={14}>
                            {t("pages.transactions.warning.suggested_links").replace(
                                "[num]",
                                suggestedLinks.items.length
                            )}
                        </Text>
                    </div>
                    <Button
                        size={"small"}
                        type={"primary"}
                        onClick={() => historyObject.push("/transactions/links/suggestions")}
                    >
                        {t("pages.transactions.warning.links_action")}
                        <CryptoIcon name={"arrow-right"} />
                    </Button>
                </div>
            );
    }, [t, suggestedLinks]);

return (
        <LoggedInLayout className={"transactions-page"}>
            <Slideshow
                renderMaxManualTransactionWarning={renderMaxManualTransactionWarning}
                renderMissingTransferTransactionWarning={renderMissingTransferTransactionWarning}
                renderSuggestedLinksWarning={renderSuggestedLinksWarning}
            />
           
        </LoggedInLayout>
    );
};

TransactionsPage.propTypes = {
    t: func,
};

export default withTranslation()(TransactionsPage);

And my SlideShow component:

/* eslint-disable no-unused-vars */
import React, { useEffect, useState, useRef, useMemo } from "react";
import "./index.scss";
import PropTypes from "prop-types";

const colors = ["#0088FE", "#00C49F", "#FFBB28"];
const delay = 10000;

export const Slideshow = (props) => {
    const [index, setIndex] = useState(0);
    const timeoutRef = useRef(null);

    function resetTimeout() {
        if (timeoutRef.current) {
            clearTimeout(timeoutRef.current);
        }
    }

    useEffect(() => {
        resetTimeout();
        timeoutRef.current = setTimeout(
            () => setIndex((prevIndex) => (prevIndex === colors.length - 1 ? 0 : prevIndex + 1)),
            delay
        );

        return () => {
            resetTimeout();
        };
    }, [index]);

    return (
        <div className="slideshow">
            <div className="slideshowSlider" style={{ transform: `translate3d(${-index * 100}%, 0, 0)` }}>
                {/* Map through the functions and render them here */}
               
            </div>

            <div className="slideshowDots">
                {colors.map((_, idx) => (
                    <div
                        key={idx}
                        className={`slideshowDot${index === idx ? " active" : ""}`}
                        onClick={() => {
                            setIndex(idx);
                        }}
                    ></div>
                ))}
            </div>
        </div>
    );
};

Slideshow.propTypes = {
    
};

export default Slideshow;

Put simply, I just want to map through the functions coming from props and render them in the Slideshow.

Any advice on this would be appreciated. Many thanks in advance!

Instead of pass the alerts as a props you can do it as a children

1:

export const TransactionsPage = (props) => {
    const { t } = props;
    const { data: profile } = apiService.useGetSingleAccountQuery();
    const { data: accountInfo } = apiService.useGetPlanQuery();

 const renderMaxManualTransactionWarning = useMemo(() => 
       accountInfo?.exceed_tx_capability ? 
            <>
                <div className={"free-trial-info"}>
                    <div className={"row"}>
                        <CryptoIcon name={"alert"} />
                        <Text size={14}>{t("pages.transactions.warning.transactions_limit")}</Text>
                    </div>
                    <Button
                        size={"small"}
                        type={"primary"}
                        onClick={() => historyObject.push("/account/subscription/change_plan")}
                    >
                        {t("pages.transactions.warning.action")}
                        <CryptoIcon name={"arrow-right"} />
                    </Button>
                </div>
            </>
        : null
        , [t, accountInfo]);
    // }, [t]);

    const renderMissingTransferTransactionWarning = useMemo(() => 
      unlinkedTransferTx?.items?.length > 0 ?
          
                <>
                    <div className={"import-warning"}>
                        <div className={"row"}>
                            <CryptoIcon name={"alert"} />
                            <Text size={14}>
                                {t("pages.transactions.warning.transfer_transactions_missing").replace(
                                    "[num]",
                                    unlinkedTransferTx.items.length
                                )}
                            </Text>
                        </div>
                        <Button
                            size={"small"}
                            type={"primary"}
                            onClick={() => historyObject.push("/transactions/transfer/list")}
                        >
                            {t("pages.transactions.warning.transfer_transactions_missing_action")}
                            <CryptoIcon name={"arrow-right"} />
                        </Button>
                    </div>
                </>
            : null
    , [t, unlinkedTransferTx]);

    const renderSuggestedLinksWarning = useMemo(() => 
        suggestedLinks?.items?.length > 0 ? 
            
                <div className={"suggested-links-info"}>
                    <div className={"row"}>
                        <CryptoIcon name={"alert"} />
                        <Text size={14}>
                            {t("pages.transactions.warning.suggested_links").replace(
                                "[num]",
                                suggestedLinks.items.length
                            )}
                        </Text>
                    </div>
                    <Button
                        size={"small"}
                        type={"primary"}
                        onClick={() => historyObject.push("/transactions/links/suggestions")}
                    >
                        {t("pages.transactions.warning.links_action")}
                        <CryptoIcon name={"arrow-right"} />
                    </Button>
                </div>
           :null
    , [t, suggestedLinks]);

return (
        <LoggedInLayout className={"transactions-page"}>
            <Slideshow>
              {renderMaxManualTransactionWarning}
              {renderMissingTransferTransactionWarning}
              {renderSuggestedLinksWarning}
            </Slideshow>
           
        </LoggedInLayout>
    );
};

TransactionsPage.propTypes = {
    t: func,
};

export default withTranslation()(TransactionsPage);

2:

import React, { useEffect, useState, useRef, useMemo } from "react";
import "./index.scss";
import PropTypes from "prop-types";

const colors = ["#0088FE", "#00C49F", "#FFBB28"];
const delay = 10000;

export const Slideshow = ({children}) => {
    const [index, setIndex] = useState(0);
    const timeoutRef = useRef(null);

    function resetTimeout() {
        if (timeoutRef.current) {
            clearTimeout(timeoutRef.current);
        }
    }

    useEffect(() => {
        resetTimeout();
        timeoutRef.current = setTimeout(
            () => setIndex((prevIndex) => (prevIndex === colors.length - 1 ? 0 : prevIndex + 1)),
            delay
        );

        return () => {
            resetTimeout();
        };
    }, [index]);

    return (
        <div className="slideshow">
            <div className="slideshowSlider" style={{ transform: `translate3d(${-index * 100}%, 0, 0)` }}>
               {children}
               
            </div>

            <div className="slideshowDots">
                {colors.map((_, idx) => (
                    <div
                        key={idx}
                        className={`slideshowDot${index === idx ? " active" : ""}`}
                        onClick={() => {
                            setIndex(idx);
                        }}
                    ></div>
                ))}
            </div>
        </div>
    );
};

Slideshow.propTypes = {
    
};

export default Slideshow;

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM