我有一个方案,其中后台服务必须定期调用其余服务。通过上下文中存储的状态确定服务必须运行的条件。我想知道最好的方法是创建/实例化此后台服务。鉴于该服务使用钩子,因此它必须位于组件中。
鉴于以下简化的结构,我希望将服务添加到MyContext元素中。但是,鉴于服务组件未返回任何内容,React给了我以下错误“ JSX元素类型'void'不是JSX元素的构造函数”-这对我来说很有意义。
<app>
<MyContext>
<MyBackgroundService />
<MyUi />
</MyContext>
</app>
我不想将所有子组件都包装到MyBackgroundService元素中。理想情况下,代码应按原样运行。一种可能的解决方案是仅返回一个空的React.Fragement
元素,但是,这感觉更像是一种肮脏的解决方法。
什么是理想的解决方案?我是否完全走错了道路,是否应该以其他方式管理后台服务的实例化?如果是这样,我如何访问上下文?
答案 0 :(得分:1)
您需要build a custom hook并在App
(<app>
)组件中调用它。
当前,您有一个使用钩子而不渲染事物的组件:
const MyBackgroundService () => {
// useHooks
// No return causes "JSX element type 'void' ..."
// With return without any functionality is useless.
// Memory waste, and loses the functionality of custom hooks
// like returning a value.
// return <></>
}
答案 1 :(得分:0)
我建议只创建一个自定义钩子,以执行所需的“后台服务”工作:
function useBackgroundService(someStateFromContext) {
const [backgroundService, setBackgroundService] = useState(null)
useEffect(() => {
const bgService = setInterval(() => {
// check the condition for running the background service
// for example, to skip the API call, or whatever
if (someStateFromContext !== 0) {
return
}
callAPI()
.then(() => {
console.log(
`ran bg service with value from context: ${someStateFromContext}`
)
})
}, 2000)
setBackgroundService(bgService)
// make sure you clean up when you no longer need it,
// for example when component unmounts
function cleanup() {
clearInterval(bgService)
}
return cleanup;
// since this `hook` relies on some value from context
// make sure you include this in your dependency array
// so that a new background service can be created,
// and old one be destroyed, when state from context changes
}, [someStateFromContext])
// optionally, return `backgroundService`
return backgroundService;
}
然后,在您的App
组件或任何其他组件中,只需使用以下hook
:
// sample context
const MyContext = React.createContext({
count: 0
})
function App() {
const myContext = useContext(MyContext)
useBackgroundService(myContext.count)
return (
<div className="App">
...
</div>
)
}
以下是示例的链接: