我有一个包含多个页面的应用程序。虽然该应用程序运行良好,但出于某种原因,当我登陆此特定页面时,窗口会显示内容,但它会无限刷新,因此无法与该页面进行交互。现在有几个 useEffects,我尝试取消注释并将 console.log 放入其中,但它们都只被触发一次,因此我得出结论,它不是由其中之一引起的。另一方面,在页面顶部创建的 ThemeSelector 组件似乎是导致错误的原因。当我围绕这个组件包装页面时,它会导致页面无限重新加载。我还在该组件中放置了一个 console.log,它会被无限触发。我已经尝试了一切,但我无法修复 ThemeSelector 以使其不会无限地重新加载。谁能告诉我如何避免它导致页面无限重新加载。是否有我没有看到的原因?
import React, { Fragment } from 'react'
import { RouteComponentProps } from 'react-router'
import { Api } from '../../Api'
import { locale_data } from '../../locale/locale_data'
import { useAppSelector } from '../../redux/hooks'
import { error, success } from '../../utilities/_alerts'
import { titles_data_LIMITED } from '../config'
import { check } from '../../assets/icons'
import 'react-responsive-combo-box/dist/index.css'
import loadScript from '../../scripts/ScriptLoader';
import { bertelsmannLogo } from '../../assets/images'
import { nfaNifteeLogo } from '../../assets/images'
import { ApplicationStateActions } from '../../redux/slices/ApplicationState'
import { useDispatch } from 'react-redux'
export const Tokentransfer: React.FC<
RouteComponentProps<{
customer: string
authtoken: string
}> & {}
> = ({
match: {
params: { customer, authtoken },
},
}) => {
const BertelsmannTheme = React.lazy(() => import('./BertelsmannTheme'));
const NFATheme = React.lazy(() => import('./NFATheme'));
const ThemeSelector = ({ children }: { children: any } ) => {
console.log("Is being rerendered");
return (
<>
<React.Suspense fallback={<></>}>
{(customer === 'bertelsmann') && <BertelsmannTheme />}
{(customer === 'nfa') && <NFATheme />}
</React.Suspense>
{children}
</>
)
}
const disableUpdate: boolean = true;
const [limitedAvailable, setLimitedAvailable] = React.useState(false)
const [titleData, setTitleData] = React.useState(titles_data_LIMITED[0])
//const [remaining, setRemaining] = React.useState('')
const [update, setUpdate] = React.useState(0)
const [langData, setLangData] = React.useState([''])
const [ld, setLd] = React.useState<any>({})
const [successBuy, setSuccessBuy] = React.useState(0)
const [imagePath, setImagePath] = React.useState('')
const [showImage, setShowImage] = React.useState(false)
const [typeImage, setTypeImage] = React.useState('')
const lang = useAppSelector((state) => state.ApplicationReducer.lang)
const loaderText = 'Processing...'
const [isLoading, setIsLoading] = React.useState(false)
const [recaptchaLoaded, setRecaptchaLoaded] = React.useState(false);
const dispatch = useDispatch()
React.useEffect(() => {
loadScript("recaptcha", process.env.REACT_APP_RECAPTCHA_SCRIPT + "?render=" + process.env.REACT_APP_RECAPTCHA_SITE_KEY, setRecaptchaLoaded);
}, []);
React.useEffect(() => {
if (lang) {
setLangData(locale_data[lang].title.tokenGift)
setLd(locale_data[lang].title)
}
}, [lang])
React.useEffect(() => {
if(!titleData) return;
const interval = setInterval(() => {
setTitleData(titleData)
}, 1000)
return () => {
clearInterval(interval);
};
}, [titleData, lang, ld?.expired])
React.useEffect(() => {
if(disableUpdate) return;
const interval = setInterval(() => {
setUpdate(update + 1)
}, 4000)
return () => {
clearInterval(interval);
};
}, [disableUpdate, update])
React.useEffect(() => {
console.log("how many times ");
dispatch(ApplicationStateActions.set_show_plain_site(true));
if(isLoading) return;
async function fetch_title_data() {
const data = await Api.get_customer_gift_limited(customer, authtoken);
if (data) {
setLimitedAvailable(true);
const td = {
_id: data._id,
category: data.assetType,
auctionStart: data.auctionStart,
auctionExpire: data.auctionExpire,
title: data.title,
title_image: data.preview,
title_big_image: data.image,
title_link: data._id,
clientId: data.clientId.clientname,
lastAuction: 0,
details: data.details,
other_details: data.other_details,
has_unlockable_content: data.has_unlockable_content,
buy_amount: data.buyAmount,
limited_amount: data.limitedAmount,
limited_available: data.limitedAvailable,
bidAuction: false,
network:data.network
}
setTitleData(td)
setImagePath(data.image)
setTypeImage(data.type_of_asset)
} else {
setLimitedAvailable(false);
}
}
if (customer && authtoken) {
fetch_title_data()
}
}, [customer, authtoken, isLoading, update,limitedAvailable, dispatch])
React.useEffect(() => {
if(typeImage === 'video' && showImage) {
setTimeout(() => (window as any).videojs('video-js', {responsive: true, fill: true}), 200)
return () => {
(window as any).videojs('video-js').dispose()
}
}
}, [showImage, typeImage])
return (
<ThemeSelector>
<Fragment>
{limitedAvailable === false ? "" :
<div className='token-transfer'>
<div className="centered">
{(() => {
switch(customer) {
case 'bertelsmann':
return <img className='tokentransferLogo' src={bertelsmannLogo} alt='item'/>
case 'nfa':
return <img className='tokentransferLogo' src={nfaNifteeLogo} alt='item'/>
default :
return ""
}
})()}
</div>
<div className='img' onLoad={() => {
if(typeImage === "video" && !showImage) {
// window.open(imagePath, '_blank')
setShowImage(true)
} else if(typeImage !== "video") setShowImage(!showImage)
}}>
{(() => {
switch (typeImage) {
case 'image':
return <img src={imagePath} alt='item' />
case 'audio':
return (() => {
return (
<>
<img src={titleData.title_image} alt='item' />
{showImage && <audio src={imagePath} autoPlay />}
</>
)
})()
case 'video':
return (() => {
return (
<video playsInline loop autoPlay muted>
<source src={imagePath} type='video/mp4' />
Your browser does not support the video tag.
</video>
)
})()
}
})()}
</div>
<div className='content flex'style={{ padding: ' 0' }}>
{/* End Left Start right */}
<div>
<div className='transfer-details'>
<div className='title' dangerouslySetInnerHTML={{ __html: titleData.title }}></div>
<div className='desc' dangerouslySetInnerHTML={{ __html: titleData.details }}></div>
<div className='desc' dangerouslySetInnerHTML={{ __html: titleData.other_details }}></div>
{ titleData.limited_available > 0
? (
<div>
<div onClick={async () => {
if(isLoading || !recaptchaLoaded) return;
setIsLoading(true)
const connected = await Api.connectIMX(true);
if(connected) {
try {
let buySuccessfull = false;
if(titleData.buy_amount === 0) {
window.grecaptcha.ready(() => {
window.grecaptcha.execute(process.env.REACT_APP_RECAPTCHA_SITE_KEY, { action: 'submit' }).then(async (token: any) => {
setIsLoading(true)
const data = (await Api.transferLimited(titleData._id, token, customer, authtoken))?.data;
if (!data || data.error) {
if (data) error(data.error)
setSuccessBuy(2)
buySuccessfull = false;
} else {
window.location.replace(`/${lang}/externalpayments`);
setSuccessBuy(1);
}
setUpdate(update + 1)
setIsLoading(false)
if(buySuccessfull) {
success("Transfer confirmed");
}
});
});
}
} catch (err: any) {
console.error(err)
error(ld?.errorBuy)
setSuccessBuy(2)
if (err.message) error(err.message)
setIsLoading(false)
setUpdate(update + 1)
}
} else {
setIsLoading(false);
}
}}>
<div className='bttn white gift-button'>
{isLoading
? loaderText
: (() => {
switch (successBuy) {
case 0:
return <div>{langData[0]}</div>
case 1:
return (
<img
src={check}
alt='Success'
style={{ width: '100px', height: '20px', zIndex: 10 }}
/>
)
default:
return <div>{langData[0]}</div>
}
})()}
</div>
</div>
</div>
)
: ""
}
</div>
</div>
{(() => {
switch(customer) {
case 'bertelsmann':
return (
<div className="centered">
<div className="transfer-footer">
<a href="https://www.bertelsmann.com/meta/privacy/" target="_blank" rel="noreferrer">Data Privacy Notices of Bertelsmann</a>
</div>
</div> )
case 'nfa':
return ""
default :
return ""
}
})()}
</div>
</div>
}
</Fragment>
</ThemeSelector>
)
}