Skip to content

Latest commit

 

History

History
197 lines (131 loc) · 5.07 KB

React.md

File metadata and controls

197 lines (131 loc) · 5.07 KB

Use data- attr in React

<Option data-name="data set name" />

See more https://developer.mozilla.org/en-US/docs/Learn/HTML/Howto/Use_data_attributes


Adding a CSS Reset in CRA

https://create-react-app.dev/docs/adding-css-reset/

```css
@import-normalize; /* bring in normalize.css styles */

/* rest of app styles */

How To Debug React Apps Like A Senior Developer

Show Hooks name

Debug Suspend

https://youtu.be/l8knG0BPr-o?t=645

Debug ErrorBoundary

https://youtu.be/l8knG0BPr-o?t=786

Perf in React

https://dev.to/headwayio/react-optimize-components-with-react-memo-usememo-and-usecallback-39h8

Class Components

  • PureComponent
  • shouldComponentUpdate

Functional Components

  • React.memo
  • useMemo
  • useCallback.

Heads up

const Header = React.memo(({ title }) => <h1>{title}</h1>, []);
export default Header;

The previous fashion will cause component to show up as Unknow in react dev tools. To fix this, wrap comp in memo after defining it, as following:

const Header = ({ title }) => <h1>{title}</h1>;
export default React.memo(Header);

What’s New in React 18

New Feature: Automatic Batching

Before 18 After 18
React event handlers promises
setTimeout
native event handlers
or any other event

React forwardRef(): How to Pass Refs to Child Components

https://dmitripavlutin.com/react-forwardref/

https://react.dev/reference/react/useImperativeHandle

https://dmitripavlutin.com/react-forwardref/#53-anonymous-component

In React dev tools an anonymous function wrapped in forwardRef() results in a component with an unmeaningful name.

https://dmitripavlutin.com/react-forwardref/#6-forwardref-in-typescript

forwardRef<V, P>() accepts 2 argument types:

  • V is the type of the value stored in a ref, which is usually an HTMLDivElement or HTMLInputElement
  • P is the props type of the wrapped component

useRef<V>() hook in TypeScript has one argument type V: denoting the value type stored in the ref. If you store DOM elements in the ref, V can be HTMLDivElement or HTMLInputElement.

Now let's annotate the parent and child components:

import { useRef, forwardRef } from "react";

export function Parent() {
  const elementRef = useRef<HTMLDivElement>(null);

  return <Child ref={elementRef} />;
}

const Child = forwardRef<HTMLDivElement>(function (props, ref) {
  return <div ref={ref}>Hello, World!</div>;
});

React Memory Leaks: How useCallback and closures can bite you

https://schiener.io/2024-03-03/react-closures

Closures and useCallback

import { useState, useCallback } from "react";

class BigObject {
  public readonly data = new Uint8Array(1024 * 1024 * 10); // 10MB of data
}

function App() {
  const [count, setCount] = useState(0);
  const bigData = new BigObject();

  const handleEvent = useCallback(() => {
    setCount(count + 1);
  }, [count]);

  const handleClick = () => {
    console.log(bigData.data.length);
  };

  return (
    <div>
      <button onClick={handleClick} />
      <ExpensiveChildComponent2 onMyEvent={handleEvent} />
    </div>
  );
}

All closures share a common context object from the time they were created. Since handleClick() closes over bigData, bigData will be referenced by this context object. This means, bigData will never get garbage collected as long as handleEvent() is being referenced. This reference will hold until count changes and handleEvent() is recreated.

Big object capture

Snappy UI Optimization with useDeferredValue

memoization required

An important thing to note: useDeferredValue only works when the slow / low-priority component has been wrapped with React.memo():

import React from 'react';
function SlowComponent({ count }) {}

export default React.memo(SlowComponent);

Working with multiple state variables

Don't:

const deferredOomph = React.useDeferredValue(oomph);
const deferredCrispy = React.useDeferredValue(crispy);
const deferredBg = React.useDeferredValue(backgroundColor);
const deferredTint = React.useDeferredValue(tint);
const deferredResolution = React.useDeferredValue(resolution);
const deferredLight = React.useDeferredValue(lightPosition);

Do:

const cssCode = generateShadows(oomph, crispy, backgroundColor, tint, resolution, lightPosition);
const deferredCssCode = React.useDeferredValue(cssCode);
return (
  <>
    {/* Other stuff omitted for brevity */}
    <CodeSnippet lang="css" code={deferredCssCode} />
  </>
);