Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

React hook useRef not working with styled-components and typescript

I've some problem using the useRef hook with a styled component.

Linter alerts me that Object is possibly 'null' inside the didMount useEffect. Any idea about this?

This is not a duplicate for 2 reason:

  • The old answer refers to the ref used in a class component, that was the only way to use it before React hooks,
  • The innerRef props isn't supported anymore in the current version of styled components.

Here's a sample snippet of my component:

import React, { useRef, useEffect } from 'react';
import styled from 'styled-components';

const StyledInput = styled.input`
  background: transparent;
`

const MyForm = () => {
  const inputRef = useRef(null);
  
  useEffect(() => {
    if (inputRef && inputRef.current) {
      inputRef.current.focus(); //Object is possibly 'null'
    }
  }, []);

  return (
    <StyledInput ref={inputRef}/>
  );
}
like image 875
vlk Avatar asked Sep 22 '19 16:09

vlk


People also ask

How do you pass ref to styled components?

We can pass in refs to a styled component to access the DOM properties and methods for the given styled component. In the code above, we created a styled input called Input . Then we passed in a ref created with the useRef hook to Input . Then in the useEffect callback, we call inputRef.

Does useRef cause Rerendering?

useState() Hook is widely used in React applications to re-render the components on state changes. However, there are scenarios where we need to track state changes without re-rendering the components. But, if we use the useRef() Hook, we can track the state changes without causing component re-renderings.

Is useRef better than useState?

useRef is powerful because it's persisted between renders. Unlike useState, useRef doesn't cause a component to re-render when the value or state changes. To make things more clear, let's look at a practical example.


2 Answers

I've finally found a solution:

const inputRef = useRef() as React.MutableRefObject<HTMLInputElement>;

It works for me:

import React, { useRef, useEffect } from 'react';
import styled from 'styled-components';

const StyledInput = styled.input`
  background: transparent;
`

const MyForm = () => {
  const inputRef = useRef() as React.MutableRefObject<HTMLInputElement>;

  useEffect(() => {
    if (inputRef && inputRef.current) {
      inputRef.current.focus();
    }
  }, []);

  return (
    <StyledInput ref={inputRef}/>
  );
}
like image 95
vlk Avatar answered Oct 18 '22 03:10

vlk


As an alternative to the current accepted answer, you can also do:

const inputRef = useRef<HTMLInputElement>(null);
like image 7
Connor M Avatar answered Oct 18 '22 04:10

Connor M