1 the introduction

UseRef is the common API, but there is also a createRef API, do you know the difference between them? You can learn when to use them with The react. useRef and react. createRef: The Difference articles.

2 an overview

UseRef only works in FunctionComponent, createRef only works in ClassComponent.

The first sentence is obvious, because Hooks cannot be used in ClassComponent.

CreateRef does not have the effect of Hooks, which are initialized as the FunctionComponent executes repeatedly:

Const valueRef = react.createref (); function App() {const valueRef = react.createref (); return <div ref={valueRef} />; }Copy the code

The above valueRef is initialized repeatedly with the Render of the App function. This is where Hooks are unique. Although they are used in normal functions, the React engine performs better than normal functions, such as initialization only once, or reference invariant.

Why does createRef work in ClassComponent? This is because ClassComponent separates the life cycle so that initialization times such as componentDidMount are executed only once.

The original finish.

3 intensive reading

So if you know how to create a Ref correctly, do you know how to update a Ref correctly?

Since Ref is an instance that runs through all of the FunctionComponent’s rendering cycles, changes can theoretically be made anywhere, such as:

function App() {
  const valueRef = React.useRef();

  valueRef.current += 1;

  return <div />;
}
Copy the code

React/FunctionComponent/Ref/Ref/Ref/Ref/Ref/Ref/Ref/Ref

As you can see, “Side effects” is not allowed during the Render phase, because this phase can be cancelled or redone by the React engine at any time.

Modifying Ref is a side effect and therefore not appropriate at this stage. As you can see, this can be done in the Commit phase, or in callback functions (out of the React life cycle).

Of course, there is one case where lazy initialization is possible:

function Image(props) {
  const ref = useRef(null);

  ✅ IntersectionObserver is created lazily once
  function getObserver() {
    if (ref.current === null) {
      ref.current = new IntersectionObserver(onIntersect);
    }
    return ref.current;
  }

  // When you need it, call getObserver()
  // ...
}
Copy the code

In the case of lazy initialization, side effects are performed at most once and only for initial assignments, so this behavior is allowed.

Why the strict restrictions on side effects? Because the FunctionComponent adds a built-in Scheduling system, it may temporarily render a React component in order to prioritize user operations.

In addition to retrieving component references and creating a Mutable object, useEffect can be used to store older values, most often to retrieve previousProps. React uses Ref to package a simple Hooks to retrieve the previous values:

function usePrevious(value) {
  const ref = useRef();
  useEffect(() => {
    ref.current = value;
  });
  return ref.current;
}
Copy the code

Because useEffect is performed after Render is complete, ref is always the last Render in the current Render, so we can use it to get Props for the last Render:

function App(props) {
  const preProps = usePrevious(props);
}
Copy the code

Again, this is thanks to the ref’s ability to “pass values through various Render closures.” Lastly, don’t abuse Ref. The more references you have, the less maintainable React is generally.

4 summarizes

What other interesting ways did you discover to use useRef? Leave a comment in the comments section.

The discussion address is: Close reading the difference between useRef and createRef · Issue #236 · dT-fe /weekly

If you’d like to participate in the discussion, pleaseClick here to, with a new theme every week, released on weekends or Mondays. Front end Intensive Reading – Helps you filter the right content.

Pay attention to the front end of intensive reading wechat public account

Copyright Notice: Freely reproduced – Non-commercial – Non-derivative – Remain signed (Creative Commons 3.0 License)