Slow input even with useTransition()

545 views Asked by At

I'm playing with the new useTransition() hook added in React 18.

I created an app highlighting the matching names. If it matches, the item gets green, otherwise red. Here how I did it:

import { useState, useTransition } from 'react';
import people from './people.json'; // 20k items

const PeopleList = ({ people, highlight, isLoading }) => {
    return (
        <>
            <div>{isLoading ? 'Loading...' : 'Ready'}</div>
            <ol>
                {people.map((name, index) => (
                    <li
                        key={index}
                        style={{
                            color: (
                                name.toLowerCase().includes(highlight)
                                ? 'lime'
                                : 'red'
                            )
                        }}
                    >
                        {name}
                    </li>
                ))}
            </ol>
        </>
    );
};

const App = () => {
    const [needle, setNeedle] = useState('');
    const [highlight, setHighlight] = useState('');
    const [isPending, startTransition] = useTransition();

    return (
        <div>
            <input
                type="text"
                value={needle}
                onChange={event => {
                    setNeedle(event.target.value);
                    startTransition(
                        () => setHighlight(event.target.value.toLowerCase())
                    );
                }}
            />
            <PeopleList
                people={people}
                highlight={highlight}
                isLoading={isPending}
            />
        </div>
    );
};

export default App;

The JSON file contains an array of 20k people. Unfortunately, the useTransition() doesn't seem to improve performance in this case. Whether I use it or not, typing in the input is very laggy, making about a 0.5s delay between each character.

My first thought was that maybe such a big DOM tree would cause a delay in the input, but it doesn't seem the case in a raw HTML page.

Why doesn't useTransition() make typing smooth in my example?

2

There are 2 answers

2
Raphael Rafatpanah On

The reason is because your app is running in React 17 mode.

Source: https://reactjs.org/blog/2022/03/08/react-18-upgrade-guide.html#deprecations

react-dom: ReactDOM.render has been deprecated. Using it will warn and run your app in React 17 mode.

3
hiamnshu negi On

How about wrapping PeopleList component in a memo.

As far as my understanding goes. Everytime when setNeedle is being called <App/> component is rerendering and then <PeopleList/> is also rerendering even though nothing changed in <PeopleList/> component.