경고: React 18에서 텍스트 콘텐츠가 일치하지 않았습니다.

8313 단어 react
안녕하세요, 최근에 제가 작업하고 있는 프로젝트가 React 18로 업그레이드되었습니다. 그때쯤 갑자기 많은 수화 문제가 콘솔에 경고/오류로 나타나기 시작했습니다. 내가 고심하고 있는 것은 "경고: 텍스트 내용이 일치하지 않습니다"입니다.

Error
이 구성 요소의 코드:

   <div className="O75-product-faq__questions is-active accordion--initialized">
                            {
                                dataForSelect.length > 1 && <h4 className="O75-product-faq__questions__name js-category-name">{props.questionsByCategories[selectedCategory?.value].name}</h4>
                            }
                            {
                                props.questionsByCategories[selectedCategory?.value].questions.map((element, i) => (
                                    <div key={i} className="O75-product-faq__questions__item">
                                        {(element.question || props.showOnlyAnswer) && <div className={`O75-product-faq__questions__item__button${openedElement === i ? ' has-accordion-open' : ''}`} onClick={() => openElement(i)}>{element.question}</div>}
                                        <AnimateHeight height={openedElement === i ? 'auto' : 0} duration={transitionDisabled ? 0 : 400}>
                                            <div className="O75-product-faq__questions__item__content" dangerouslySetInnerHTML={{ __html: element.answer }} />
                                        </AnimateHeight>
                                    </div>))
                            }
                        </div>


이 문제는 클라이언트와 서버 측 렌더링의 차이로 인해 발생한다는 것을 알고 있지만 해결 방법을 모르고 인터넷에서 찾은 어떤 것도 내 경우에 효과가 없었습니다.

문제가 앞서 언급한 부분이 아닌 경우 파일의 나머지 부분:

import React, { useMemo, useState } from 'react';
import type { ReactElement } from 'react';
import AnimateHeight from 'react-animate-height';
import { BaseSelect, SelectOption } from '../molecules/base-select';
import type { FrequentlyAskedCategory } from './frequentlyAskedQuestion';
import { fromBase64 } from '../shared-services/base64Service';

interface FaqPanelProps {
    mainTitle?: string;
    menuTitle?: string;
    showOnlyAnswer: boolean;
    currentPageUrl: string;
    questionsByCategories: Record<string, FrequentlyAskedCategory>,
    faqStructuredDataBase64: string;
}

const FAQPanel = (props: FaqPanelProps): ReactElement => {
    const categories = Object.keys(props.questionsByCategories);
    const dataForSelect: Array<SelectOption> = categories.map(key => ({ label: props.questionsByCategories[key].name, value: key }));
    const noOpenedElementIndex = -1;

    const [openedElement, setOpenedElement] = useState<number>(-1);
    const [selectedCategory, setSelectedCategory] = useState<SelectOption>(dataForSelect.length > 0 ? dataForSelect[0] : null);
    const [transitionDisabled, setTransitionDisabled] = useState<boolean>(false);
    const parsedStructuredData = useMemo(() => {
        if(props.faqStructuredDataBase64 != null && props.faqStructuredDataBase64 !== ""){
           return fromBase64(props.faqStructuredDataBase64);
        }

        return "";
    }, [props.faqStructuredDataBase64]);

    const selectNewCategory = (option: SelectOption): void => {
        setTransitionDisabled(true);
        setOpenedElement(noOpenedElementIndex);
        setSelectedCategory(option);
    }

    const openElement = (index: number): void => {
        if (transitionDisabled) {
            setTransitionDisabled(false);
        }
        setOpenedElement(index === openedElement ? noOpenedElementIndex : index);
    }

    const speakableJson = JSON.stringify({
        "@context": "https://schema.org/",
        "@type": "WebPage",
        "name": props.mainTitle,
        "speakable":
            [".O75-product-faq__headline",
                ".O75-product-faq__questions__item"],
        "url": props.currentPageUrl
    });

    const hasFAQStructuredData = parsedStructuredData != null && parsedStructuredData !== "";
    return (
        <div className="container">
            <section className="O75-product-faq" >
                {
                    props.mainTitle
                        ? <h2 className="O75-product-faq__headline">{props.mainTitle}</h2>
                        : <h4 className="O75-product-faq__categories-headline">{props.menuTitle}</h4>
                }
                <div className="flex">
                    {dataForSelect.length > 1 &&
                        <div className="O75-product-faq__categories">
                            <div className="filter__list is-hidden-sm filter">
                                {
                                    dataForSelect.map((element, i) => (
                                        <button className={`filter__btn js-filter__btn${element.value === selectedCategory?.value ? " is-active" : ""}`} key={i} onClick={() => selectNewCategory(element)}>
                                            {element.label}
                                        </button>))
                                }
                            </div>
                            <div className="filter__group is-hidden-md">
                                <BaseSelect selectedValue={selectedCategory}
                                    handleChange={selectNewCategory}
                                    options={dataForSelect} />
                            </div>
                        </div>
                    }
                    {categories.length > 0 &&
                        <div className="O75-product-faq__questions is-active accordion--initialized">
                            {
                                dataForSelect.length > 1 && <h4 className="O75-product-faq__questions__name js-category-name">{props.questionsByCategories[selectedCategory?.value].name}</h4>
                            }
                            {
                                props.questionsByCategories[selectedCategory?.value].questions.map((element, i) => (
                                    <div key={i} className="O75-product-faq__questions__item">
                                        {(element.question || props.showOnlyAnswer) && <div className={`O75-product-faq__questions__item__button${openedElement === i ? ' has-accordion-open' : ''}`} onClick={() => openElement(i)}>{element.question}</div>}
                                        <AnimateHeight height={openedElement === i ? 'auto' : 0} duration={transitionDisabled ? 0 : 400}>
                                            <div className="O75-product-faq__questions__item__content" dangerouslySetInnerHTML={{ __html: element.answer }} />
                                        </AnimateHeight>
                                    </div>))
                            }
                        </div>
                    }
                </div>
                {hasFAQStructuredData && <script suppressHydrationWarning type="application/ld+json" dangerouslySetInnerHTML={{__html:parsedStructuredData } }></script>}
                <script suppressHydrationWarning type="application/ld+json" dangerouslySetInnerHTML={{__html: speakableJson}} ></script>
            </section>
        </div>
    )
}

export { FAQPanel };
export type { FaqPanelProps }



더 나은 가독성을 위해 stackblitz의 코드 링크:

File

이 문제를 해결하는 방법을 아는 사람이 있습니까? 나는 아이디어가 완전히 떨어졌습니다.

좋은 웹페이지 즐겨찾기