-
Notifications
You must be signed in to change notification settings - Fork 4.2k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[Basic] useRef Hook Documentation. #388
Comments
very nice issue! clearly we are wrong in our useRef notes. i think @ferdaber might have some insight as to why |
According to useRef Hook Type Definitions.
From Playground.
These ref matches the first two type definitions.
|
ok so check out this example though: (playground) export default function MyComponent() {
const ref1 = React.useRef<HTMLDivElement>(null!); // MutableRefObject
const ref2 = React.useRef<HTMLDivElement>(null); // RefObject
React.useEffect(() => {
console.log(ref1.current.innerHTML);
// TypeScript won't require null-check e.g. ref1 && ref1.current
console.log(ref2.current.innerHTML);
// Type error: Object is possibly 'null'.
});
return [
<div ref={ref1}> etc </div>,
<div ref={ref2}> etc </div>
];
} the goal is to not require null checks because the ref is always bound to the element in this case. i think this is why i made the original recommendation. |
If the goal is not to require null checks then its absolutely correct but stating ref1.current will be read-only is wrong. As it is a MutableRefObject so it is not read-only. |
alright :) |
i made those tweaks here: https://github.com/typescript-cheatsheets/react/pull/389/files , lmk if any changes but otherwise thank you for the feedback :) |
would this be more explanatory? import * as React from "react";
export default function MyComponent() {
const ref1 = React.useRef<HTMLDivElement>(null!); // MutableRefObject
const ref2 = React.useRef<HTMLDivElement>(null); // RefObject
React.useEffect(() => {
ref1.current=ref2.current!;
// ok
ref2.current=ref1.current;
//Cannot assign to 'current' because it is a read-only property.(2540)
console.log(ref1.current.innerHTML);
// TypeScript won't require null-check e.g. ref1 && ref1.current
console.log(ref2.current.innerHTML);
// Type error: Object is possibly 'null'.
});
return [
<div ref={ref1}> etc </div>,
<div ref={ref2}> etc </div>
];
} |
@bochen2014 i dont feel strongly about this code sample 🤷🏽 |
@sw-yx I think we should not encourage the null check bypassing here. The reason is that check is valid in real life, because the developer may forget to assign the ref to an element in his render, or if the ref-ed element is conditionally rendered: const Foo = () => {
const ref1 = useRef<HTMLDivElement>(null); // RefObject
useEffect(() => {
console.log(ref1.current); // This will be null
});
return <div> etc </div>; // Oops, I forgot to assign the ref
} const Foo = () => {
const ref1 = useRef<HTMLDivElement>(null); // RefObject
useEffect(() => {
console.log(ref1.current); // Only works on Monday!
});
return isMonday ? <div ref={ref1} /> : <div> etc </div>;
} @sw-yx would you mind if I have a PR to clarify this more? |
haha nice example @thien-do. yes PR welcome, but i think giving the 3 examples and letting people decide based on the pros and cons feels right. otherwise i'll just keep getting more and more issues fighting back and forth haha |
This is my suggestion follow a [comment](typescript-cheatsheets#388 (comment)) in typescript-cheatsheets#388 . The problem with the current guide is that most newcomers will use the `null!` approach, which could cause hidden bug in practice, when the developer forget to assign the ref or conditionally render the ref-ed element. I saw this a lot, because this guide is the official reading recommendation in my company, and I keep seeing that bug. My proposal is to not bypassing TypeScript, but let TypeScript does its job, by correctly tell it whether we need a RefObject and MutableRefObject. This also follows React's official guides, where there are 2 corresponding use cases (DOM access and mutable variable)
What cheatsheet is this about? (if applicable)
Basic cheatsheet
What's your issue or idea?
According to the documentation useRef Hook has two options.
The first option will make
ref1.current
read-only. But after trying out some examples I feel there are some issues. As it shows MutableRefObject for the first option. Soref1.current
is not read-only.I am exploring TypeScript with React so maybe I am missing something. Can someone please help me with this?
(If applicable) Reproduction of issue in TypeScript Playground
Playground
The text was updated successfully, but these errors were encountered: