farmcontrol-ui/src/components/Dashboard/context/DashboardObjectToolsContext.jsx
Tom Butcher e446098a76
All checks were successful
farmcontrol/farmcontrol-ui/pipeline/head This commit looks good
Big performance increase.
2026-09-19 13:07:30 +01:00

91 lines
2.3 KiB
JavaScript

import {
createContext,
useCallback,
useContext,
useEffect,
useMemo,
useRef,
useState
} from 'react'
import PropTypes from 'prop-types'
import { NavigationTabActiveContext } from './NavigationTabsContext'
const DashboardObjectToolsContext = createContext()
export const DashboardObjectToolsProvider = ({ children }) => {
const [currentObjectTools, setCurrentObjectToolsState] = useState(null)
const ownerRef = useRef(null)
const setCurrentObjectTools = useCallback((tools, ownerId) => {
ownerRef.current = ownerId
setCurrentObjectToolsState(tools)
}, [])
const clearCurrentObjectTools = useCallback((ownerId) => {
if (ownerRef.current !== ownerId) {
return
}
ownerRef.current = null
setCurrentObjectToolsState(null)
}, [])
const value = useMemo(
() => ({
currentObjectTools,
setCurrentObjectTools,
clearCurrentObjectTools
}),
[clearCurrentObjectTools, currentObjectTools, setCurrentObjectTools]
)
return (
<DashboardObjectToolsContext.Provider value={value}>
{children}
</DashboardObjectToolsContext.Provider>
)
}
DashboardObjectToolsProvider.propTypes = {
children: PropTypes.node.isRequired
}
// eslint-disable-next-line react-refresh/only-export-components
export const useDashboardObjectToolsContext = () => {
const context = useContext(DashboardObjectToolsContext)
if (!context) {
throw new Error(
'useDashboardObjectToolsContext must be used within a DashboardObjectToolsProvider'
)
}
return context
}
// eslint-disable-next-line react-refresh/only-export-components
export const useDashboardObjectTools = (tools) => {
const { setCurrentObjectTools, clearCurrentObjectTools } =
useDashboardObjectToolsContext()
const store = useContext(NavigationTabActiveContext)
const ownerIdRef = useRef(null)
if (ownerIdRef.current == null) {
ownerIdRef.current = Symbol('dashboardObjectTools')
}
useEffect(() => {
const sync = () => {
if (!store.getSnapshot()) return
setCurrentObjectTools(tools, ownerIdRef.current)
}
sync()
return store.subscribe(sync)
}, [setCurrentObjectTools, store, tools])
useEffect(() => {
const ownerId = ownerIdRef.current
return () => clearCurrentObjectTools(ownerId)
}, [clearCurrentObjectTools])
}
export { DashboardObjectToolsContext }