我正在使用 sdk,根据文档我必须加载脚本:
<body>
<script>
my sdk code
my sdk code
my sdk code
</script>
..
..
</body>
如何查看标签内部 我有 sdk 代码。我正在使用 reactJs,我想在 useEffect
Hook 中加载这个脚本。
问题:如何不在body标签中而是在useEffect hook中运行sdk的脚本?
最佳答案
您需要在 React 组件内动态添加脚本标签。执行此操作的最佳方法是使用上下文 API。它将提供一个加载脚本和启动 FB SDK 的单一点,并且可以让每个 child 知道何时加载脚本并且 SDK 可以使用。
FbSdkScript.js
import React, {
createContext,
useContext,
useState,
useEffect
} from 'react'
// Context.
export const FbSdkScriptContext = createContext()
// Create a custom hook to use the context.
export const useFbSdkScriptContext = () => useContext(FbSdkScriptContext)
// Provider of context.
const FbSdkScriptProvider = ({
appId,
autoLogAppEvents = true,
xfbml = true,
version = 'v8.0',
children
}) => {
const [hasLoaded, setHasLoaded] = useState(false)
const [isReady, setIsReady] = useState(false)
/**
* Extra security measure to check if the script has
* already been included in the DOM
*/
const scriptAlreadyExists = () =>
document.querySelector('script#fb-sdk') !== null
/**
* Append the script to the document.
* Whenever the script has been loaded it will
* set the isLoaded state to true.
*/
const appendSdkScript = () => {
const script = document.createElement('script')
script.id = 'fb-sdk'
script.src = 'https://connect.facebook.net/en_US/sdk.js'
script.async = true
script.defer = true
script.crossOrigin = 'anonymous'
script.onload = () => setHasLoaded(true)
document.body.append(script)
};
/**
* Runs first time when component is mounted
* and adds the script to the document.
*/
useEffect(() => {
if (!scriptAlreadyExists()) {
appendSdkScript()
}
}, []);
/**
* Whenever the script has loaded initialize the
* FB SDK with the init method. This will then set
* the isReady state to true and passes that
* through the context to the consumers.
*/
useEffect(() => {
if (hasLoaded === true) {
FB.init({
appId,
autoLogAppEvents,
xfbml,
version
})
setIsReady(true)
}
}, [hasLoaded])
return (
<FbSdkScriptContext.Provider value={{ isReady, hasLoaded }}>
{children}
</FbSdkScriptContext.Provider>
)
}
export default FbSdkScriptProvider
共享组件本身现在无需担心。它只需要知道脚本什么时候加载,FB SDK 已经初始化。它将通过 Context API 的 isReady
状态获取该信号。
FbShareDialog.js
import React, { useEffect } from 'react'
import { useFbSdkScriptContext } from './FbSdkScript'
/**
* This is the button that will trigger the dialog.
* It uses the context created in the previous snippet to
* know when the script has loaded and the API is ready
* to use.
*/
const FbShareDialog = ({ method = 'share', href }) => {
const { isReady } = useFbSdkScriptContext()
/**
* Open share dialog when the button is clicked.
* This will only be available when the isReady
* state is true.
*/
const handleClick = () => {
FB.ui({
method,
href,
}, response => {
console.log(response)
})
}
/**
* If FB SDK is not yet ready, don't render the button.
*/
if (!isReady) {
return null
}
/**
* Otherwise do render the button and set an onClick
* event listener which triggers the dialog.
*/
return (
<button onClick={handleClick}>Share me</button>
)
}
export default FbShareDialog
所有这些都集中在一个组件中,其中上下文提供程序是共享对话框按钮的父级。您只需传递 appId
即可让 FbSdkScriptProvider
组件正常工作。并将 href
添加到按钮以告诉 FB.ui
引用什么 href。
App.js
import React from 'react'
import FbSdkScriptProvider from './FbSdkScript'
import FbShareDialog from './FbShareDialog'
const App = () => (
<FbSdkScriptProvider appId={'your-app-id'}>
<FbShareDialog href={'https://developers.facebook.com/docs/'} />
<FbSdkScriptProvider/>
)
https://stackoverflow.com/questions/64297146/
相关文章:
reactjs - 不能在 JSX 属性中使用 bool 值
python - 为什么 python 的 "gc.collect()"没有按预期工作?
python-3.x - Python Pandas : groupby one column, 只
python-3.x - Pygame - 不存在 "Setup"文件,正在运行 "buildcon
java - 如何使用 void set 方法在静态常量帮助程序类中创建对象?
javascript - 在 React Native 中安排本地通知不起作用