Skip to content

Instantly share code, notes, and snippets.

@JoelCodes
Last active April 8, 2020 15:20
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save JoelCodes/38bef680a1d4f0fe94132388789f3bf0 to your computer and use it in GitHub Desktop.
Save JoelCodes/38bef680a1d4f0fe94132388789f3bf0 to your computer and use it in GitHub Desktop.
React Ref methods demo
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
</head>
<body>
<div id="root"></div>
<script src="./index.tsx"></script>
</body>
</html>
import {render} from 'react-dom';
import React, { useRef, MutableRefObject, useEffect } from 'react';
import { forwardRefFunction } from './utils';
type ChildMethods = {
doThing(i:number):void
};
type ChildProps = {
sendMessageToParent(i:number):void
}
const RefChild = forwardRefFunction<ChildMethods, ChildProps>((props, ref) => {
ref({
doThing: (i:number) => {
console.log('Thing Done!', i);
}
});
return <h1>Hi! <button onClick={() => props.sendMessageToParent(42)}></button></h1>;
})
function Demo(){
const childref:MutableRefObject<ChildMethods> = useRef();
useEffect(() => {
if(childref.current){
childref.current.doThing(1)
}
}, []);
return <RefChild sendMessageToParent={(i:number) => {
console.log('Hi parent', i);
}} ref={childref}/>
}
render(<Demo/>, document.getElementById('root'));
{
"name": "react-ref-methods",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"start": "parcel index.html"
},
"keywords": [],
"author": "",
"license": "ISC",
"dependencies": {
"@types/react": "^16.9.31",
"@types/react-dom": "^16.9.6",
"parcel": "^1.12.4",
"react": "^16.13.1",
"react-dom": "^16.13.1",
"typescript": "^3.8.3"
}
}
{
"compilerOptions": {
"lib": ["DOM", "ESNext"],
"jsx": "react",
"esModuleInterop": true
}
}
import { PropsWithChildren, ReactElement, forwardRef } from "react";
type ForwardRefFunctionRenderFunction<T, P = {}> =
(props: PropsWithChildren<P>, ref: ((instance: T) => void)) => ReactElement | null;
// Generalizes forwardRef to use ref function style even if null or refObject is used.
export function forwardRefFunction<T, P = {}>(render: ForwardRefFunctionRenderFunction<T, P>){
return forwardRef<T, P>((props, ref) => {
const handleRef = (forwardRef) => {
if(!ref) return;
if(typeof ref === 'object'){
ref.current = forwardRef;
} else if(typeof ref === 'function'){
ref(forwardRef)
}
}
return render(props, handleRef);
})
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment