我使用的是sdk,根据文档我必须加载脚本:
<body>
<script>
my sdk code
my sdk code
my sdk code
</script>
..
..
</body>
如何查看内部标签,我有sdk代码。我正在使用reactJs,并且想将此脚本加载到useEffect
挂钩中。
问题:如何在 useEffect 挂钩中而不是在body标签中运行sdk脚本?
答案 0 :(得分:0)
您需要在React组件内部动态添加脚本标签。最好的方法是使用Context API。它将提供一个加载脚本的点,并启动FB SDK,并可以让每个孩子知道何时加载脚本以及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 [isLoaded, setIsLoaded] = 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 = () => setIsLoaded(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 (isLoaded === true) {
FB.init({
appId,
autoLogAppEvents,
xfbml,
version
})
setIsReady(true)
}
}, [isLoaded])
return (
<FbSdkScriptContext.Provider value={{ isReady={isReady} }}>
{children}
</FbSdkScriptContext.Provider>
)
}
export default FbSdkScriptProvider
共享组件本身现在无需担心。它只需要知道何时加载脚本和FB SDK已初始化。它将通过上下文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,
}, function(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/>
)