Оптимизация получения данных API с помощью пользовательских хуков React при поиске по изменению ключевого слова - PullRequest
0 голосов
/ 19 июня 2020

Я новичок в React Hooks. Я пишу небольшой код, который отображает пользователю список курсов. Он содержит 2 основных компонента CourseList и Course и настраиваемый хук useCourseList. Вот код настраиваемого хука:

function useCourseList(searchString) {
  const [courses, setCourses] = useState([]);

  useEffect(() => {
    function handleCourseListUpdating(nextCourses) {
      setCourses(nextCourses);
    }

    getCourses(searchString, handleCourseListUpdating)

    return () => {
      setCourses([]);
    }
  }, [searchString]);

  return courses;
}

Приведенный выше код извлекает данные API по строке поиска с помощью функции getCourses. Затем он обновляет полученные данные до состояния courses, которое отображается компонентом CourseList. Функция useEffect запускается с searchString в качестве зависимостей, чтобы продолжать обновлять данные курсов после изменения строки поиска.

Веб-браузер обновляется много раз в соответствии с каждым изменением символа в строке поиска, хотя результаты данных по этим изменениям ключевых слов совпадают. Например, мы ищем игровой курс по ключевому слову «Игра». Затем он 4 раза вызывает useEffect один за другим с «G», «Ga», «Gam» и «Game». Эти ключевые слова дают те же результаты с моими текущими данными api, но они постоянно обновляются React DOM через веб-интерфейс. Это приводит к тому, что браузер мигает 4 раза , что не нужно. Это также создает неудобства для пользователя.

Есть ли какое-либо решение, чтобы предотвратить обновление пользовательского интерфейса, поскольку данные все еще согласованы? Есть ли проблемы с потоком данных?

Для демонстрации вы можете увидеть полный пример кода здесь: CodeSandbox

1 Ответ

0 голосов
/ 19 июня 2020

Есть 2 изменения, которые вы можете сделать для лучшего взаимодействия с пользовательским интерфейсом

  • Отказ от вызова API для поиска
  • Не устанавливать состояние пустым при использовании Очистка эффекта

Вы можете написать свою собственную функцию отладки или использовать ее из библиотеки, такой как loda sh или подчеркивание. Как только вы это сделаете, вы можете использовать useMemo для создания защищенного экземпляра функции getCourses и вызвать его внутри useEffect

const debounce = (fn, delay) => {
  let timer = null;
  return function(...args) {
    if (timer){
      clearInterval(timer);
    }
    timer = setTimeout(() => {
      fn.apply(this, args);
    }, delay)
  }
}
// A custom Hook
function useCourseList(searchString) {
  const [courses, setCourses] = useState([]);
  const getDebouncedCourses = useMemo(() => debounce(getCourses, 300), []);
  useEffect(() => {
    function handleCourseListUpdating(courses) {
      setCourses(courses);
    }

    getDebouncedCourses(searchString, handleCourseListUpdating);
  }, [searchString, getDebouncedCourses]);

  return courses;
}

// CourseList component
function CourseList() {
  const [searchString, setSearchString] = useState('');
  const courses = useCourseList(searchString)

  return (
    <div>
      {courses ? (
        <div>
          <TextField style={{ padding: 24 }}
            id="searchInput"
            placeholder="Search for Courses"
            margin="normal"
            onChange={event => setSearchString(event.target.value)}
          />
          <Grid container spacing={4} style={{ padding: 24 }}>
            {courses.map((course, index) => (
              <Grid key={index} item xs={12} sm={6} lg={4} xl={3}>
                <Course course={course} />
              </Grid>
            ))}
          </Grid>
        </div>
      ) : "No courses found"}
    </div>
  );
}

Edit FORM VALUES

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...