React/NextJS:只为未通过身份验证的用户加载外部脚本



我们正在尝试加载广告脚本,但前提是用户未通过身份验证。注意:我们使用的是Next.js

以下是我们目前加载广告脚本的方式(注意,这是一个浓缩的示例(。

const AdContext = createContext()
export default AdContext
export const useAd = () => useContext(AdContext)
export const AdProvider = ({ children }) => {
const { currentUserIsSilverPlus } = useAuth()
const loadAds = useCallback(() => {
// ... Pushes ad blocks into divs/ad placement area...
}, [currentUserIsSilverPlus])
const contextValues = { loadAds }
return (
<AdContext.Provider value={contextValues}>
<Script
type="text/javascript"
src={`//external-script.js`}
data-cfasync="false"
onLoad={loadAds}
/>
{children}
</AdContext.Provider>
)
}

我尝试了以下操作,但效果不太好,因为当页面最初加载时,currentUserIsSilverPlus被设置为false(然后很快切换为true(。

if(!currentUserIsSilverPlus) {
return (
<AdContext.Provider value={contextValues}>
<Script
type="text/javascript"
src={`//monu.delivery/site/a/9/598bde-eb57-4f38-a35e-8d84df26769e.js`}
data-cfasync="false"
onLoad={loadAds}
/>
{children}
</AdContext.Provider>
)
} else {
return (
<AdContext.Provider value={contextValues}>
{children}
</AdContext.Provider>
)
}
}

我还尝试将脚本加载移到useEffect中,但出现了同样的问题——始终加载脚本。

useEffect(() => {
if(!currentUserIsSilverPlus) {
return (
<Script
type="text/javascript"
src={`//external-script.js`}
data-cfasync="false"
onLoad={loadAds}
/>
)
}
}, [currentUserIsSilverPlus])

return (
<AdContext.Provider value={contextValues}>
{loadAdScript()}
{children}
</AdContext.Provider>
)

如何使脚本仅在currentUserIsSilverPlus为True时加载(尽管在加载时最初为False(。

编辑:应评论者的请求添加身份验证代码。

const AuthContext = createContext()
export default AuthContext
export const AuthProvider = ({ children, isProtected = false }) => {
const [loading, setLoading] = useState(false)
const [userLoaded, setUserLoaded] = useState(false)
const [currentUser, setCurrentUser] = useState(null)
const [currentUserRole, setCurrentUserRule] = useState("Free - Bronze")
const [currentUserIsSilverPlus, setCurrentUserIsSilverPlus] = useState(false)
const [currentUserIsGoldPlus, setCurrentUserIsGoldPlus] = useState(false)
const [currentUserIsDiamondPlus, setCurrentUserIsDiamondPlus] =
useState(false)
const [hyvorSSO, setHyvorSSO] = useState({})
const [emailHasBeenSent, setEmailHasBeenSent] = useState(false)
const router = useRouter()
const updateUserInfo = useCallback(async user => {
setHyvorSSO(HYVOR_TALK_CONFIG.sso)
setCurrentUser(user)
setUserLoaded(true)
if (user) {
const stripeRole = await getUserStripeRole(user)
if (stripeRole) {
setCurrentUserRule(stripeRole)
setCurrentUserIsSilverPlus(true)
}
if (stripeRole === "PRO-Gold") {
setCurrentUserIsSilverPlus(true)
setCurrentUserIsGoldPlus(true)
}
if (stripeRole === "PRO-Diamond") {
setCurrentUserIsSilverPlus(true)
setCurrentUserIsGoldPlus(true)
setCurrentUserIsDiamondPlus(true)
}
}
}, [])
useEffect(() => {
registerUserUpdateEventListener(updateUserInfo)
}, [updateUserInfo])
useEffect(() => {
if (isProtected && userLoaded && !currentUser) router.push("/login")
}, [isProtected, userLoaded, currentUser, router])
const contextValues = {
currentUser,
currentUserRole,
currentUserIsSilverPlus,
currentUserIsGoldPlus,
currentUserIsDiamondPlus,
hyvorSSO,
emailHasBeenSent,
userLoaded,
isNotLoggedIn: userLoaded && !currentUser,
signUp,
signIn,
signOut,
manageAccount,
resetPassword: resetUserPassword,
sendVerificationEmail,
changeEmail,
startCheckoutSession,
}
if (loading || (isProtected && !userLoaded)) return <LoaderBaseball />
return (
<AuthContext.Provider value={contextValues}>
{children}
</AuthContext.Provider>
)
}

在检查currentUserIsSilverPlus之前,您可以使用userLoaded进行检查

const AdContext = createContext()
export default AdContext
export const useAd = () => useContext(AdContext)
export const AdProvider = ({ children }) => {
const { currentUserIsSilverPlus, userLoaded } = useAuth()
const loadAds = useCallback(() => {
// ... Pushes ad blocks into divs/ad placement area...
}, [currentUserIsSilverPlus])
const contextValues = { loadAds }

//if user data is not loaded yet, we don't need to have that script
//and in the meanwhile, we also check `currentUserIsSilverPlus`  
return (
<AdContext.Provider value={contextValues}>
{userLoaded && !currentUserIsSilverPlus && <Script
type="text/javascript"
src={`//external-script.js`}
data-cfasync="false"
onLoad={loadAds}
/>}
{children}
</AdContext.Provider>
)
}

最新更新