Share refs between sibling components
See original GitHub issueI posted a question on Stack Overflow an hour ago which details my entire problem. So please make sure to read that.
I’ll share what I’ve tried after posting the question. I got to know about useImperativeHandle
hook which allows to call a function in child component. So I gave it a shot.
App.tsx
is my parent component & Konva.tsx
is my child component. Konva.tsx
has my canvas & App.tsx
has a button to Download Image
.
App.tsx
import * as React from 'react'
import { Konva } from '@/components/index'
const App = () => {
const stageRef = React.useRef()
return (
<>
<Konva className="flex-grow" ref={stageRef} />
<button onClick={() => stageRef.current.downloadImage()}>
Download Image
</button>
</>
)
}
export default App
I used useImperativeHandle
& in it I have a function downloadImage
which should be called by the parent.
Konva.tsx
import * as React from 'react'
import { observer } from 'mobx-react'
import { useFrameItStore } from '@/store/index'
import { BrowserWindow } from '@/components/index'
import type { Window } from '@/types/index'
import type { Stage as StageType } from 'konva/types/Stage'
interface IProps {
className?: string
}
interface ForwardedRef {
downloadImage: Function
}
export const Konva = observer(
React.forwardRef<ForwardedRef, IProps>(
({ className }: IProps, forwardedRef) => {
const frameItStore = useFrameItStore()
const browser: Window = frameItStore.browser
const stageRef = React.useRef<StageType>(null)
React.useImperativeHandle(
forwardedRef,
() => ({
downloadImage: () =>
stageRef.current
?.getStage()
.toDataURL({ mimeType: 'image/jpeg', quality: 1 }),
}),
[]
)
return (
<Stage
width={browser.width}
height={browser.height}
ref={stageRef}
className={className}
>
<Layer>
<BrowserWindow />
</Layer>
</Stage>
)
}
)
)
However, I get 2 TS errors which I’m not sure how to solve:
First is in App.tsx
on ref
in <Konva />
component
Type ‘MutableRefObject<undefined>’ is not assignable to type ‘((instance: ForwardedRef | null) => void) | RefObject<ForwardedRef> | null | undefined’. Type ‘MutableRefObject<undefined>’ is not assignable to type ‘RefObject<ForwardedRef>’. Types of property ‘current’ are incompatible. Type ‘undefined’ is not assignable to type ‘ForwardedRef | null’.
Second is on stageRef
in the same file
Object is possibly ‘undefined’.
Basically, I have a sibling to Konva.tsx
called Options.tsx
where I’ll be calling Download Image
but I’ve simplified it for now to call it in App.tsx
but I think it should be easy enough to move it to the child once I figure this thing out.
I also have a MobX store where I used to keep this downloadImage
function as I’ve described it on StackOverflow but I thought that was unnecessary.
Any other answers appreciated. I’m not sure if this is the correct way so any help is good 😃
Issue Analytics
- State:
- Created 3 years ago
- Comments:7 (3 by maintainers)
Top GitHub Comments
Because TS doesn’t know what type you are going to use here:
You may need something like:
Oh yes, I’m just making it valid to the question asked. For example, I still have to figure out how to pass it from
App.tsx
toOptions.tsx
& then I’ll post it 😃