Как стать автором
Обновить

Лучшие подходы и решения для уменьшения кода на React. Часть 1

Время на прочтение3 мин
Количество просмотров7.5K
Автор оригинала: Rahul Sharma

Доброго времени суток! Здесь вы сможете ознакомится с переводом серии статей Rahul Sharma, в которой вы найдете способы, и примеры к ним, уменьшения Вашего кода на React.
Всего в данной серии 3 статьи:

Введение

Я работаю с React последние несколько лет и использовал его в нескольких проектах. При работе на разных проектах я выделил простые паттерны, с которыми и хочу поделиться в данных статьях. Но хватит лишних слов, давайте приступать.

1. Создавайте собственные хуки для Redux

Я не фанат использования redux, но использовал библиотеку в нескольких проектов. А redux-thunk и вовсе использовался почти во всех проектах, над которыми работал. Я обнаружил, что использование данного кода довольно-таки универсально.

const useUser = () => {
  const dispatch = useDispatch();
  const state = useSelector(); // получение данных авторизации, как пример

  const fetchUser = (id) => {
      return fetch(`/api/user/${id}`).then((res) => res.json())
       .then((user) => dispatch({type: "FETCH_USER", payload: user}));
    };

  const fetchUsers = () => {
      return fetch('/api/users').then((res) => res.json())
      .then((user) => dispatch({type: "FETCH_USERS", payload: user}));
    };
  return { fetchUser, fetchUsers };
}

Внутри компонента

const { fetchUser } = useUser();
useEffect(() => fetchUser(1), []);

Примечание: как вы можете заметить, нет необходимости создавать много функций для обработки всех redux экшенов.
Мы можем также использовать useSelector хук для получения любой информации из redux.

2. Используйте объект вместо switch внутри reducer

Плохая идея, если вы хотите использовать много switch ключей для обработки. Вы можете использовать объекты как альтернатива для switch. Это улучшит читаемость и упростит поддержку.

const actionMap = {
  INCREMENT: (state, act) => ({...state, count: state.count + 1 }),
  DECREMENT: (state, act) => ({...state, count: state.count - 1 }),
}

const reducer = (state, action) => {
  const handler = actionMap[action.type];
  return handler ? handler(state, action) : state;
};

Примечание: переменная с ключами должна быть объявлена отдельно, иначе она будет постоянно перевызываться. Сложность поиска switch O (log n), у map (объект) же O (1).

3. Создайте хук для REST запросов.

Вы можете использовать браузерное fetch API и создать собственный хук для избегания повтора кода. К примеру, получение данных из API для обновления состояния приложения и отрисовки.

const useFetch = (input, { auto, ...init }) => {
  const [result, setResult] = useState([null, null, true]);

  const fetcher = useCallback(
    (query, config) =>
      fetch(query, config)
        .then((res) => res.json())
        .then((data) => setResult([null, data, false]))
        .catch((err) => setResult([err, null, false])),
    [input, init]
  );

  useEffect(() => {
    if (auto) fetcher(input, init);
  }, []); // Если необходимо получить данные только один раз, делайте так
  
  return [...result, fetcher];
  //fetcher(refetch) это либо функция либо может быть использованно для отправки запросов
};

Внутри компонента

const Users = () => {
  const [err, users, loading, refetch] = useFetch(`/api/users`, {auto:true});

  const onClick = () => refetch(...);

  return (
    <div>
      {users.map((user) => <User key={user.id} user={user} />)}
    </div>
  );
}

Примечание: это похоже на react-query/useSWR, и обе библиотеки могут предложить гораздо больше функционала. Вы можете использовать их, но, если есть ограничения в вашем проекте, вы можете использовать данный код как альтернативу.

4. Разделение кода

Используйте React.lazy, это мощный инструмент, который позволяет загружать ваши компоненты, только когда они необходимы. React.lazy функция дает возможность отображать динамически импортированные компоненты, как обычные.

Хорошее место для начала, это роутер. При обычном решении, перед тем как отобразить элементы на странице, вам приходится загружать все компоненты сразу, что является не хорошим решением, так как это занимает дополнительное время. Даже, когда у нас нет необходимости показывать часть из компонентов.

Мы можем использовать react.lazy для загрузки компонентов асинхронно. Так, когда вы на первой (Home) странице, вы загружаете только домашнюю страницу. А когда переходите на вторую страницу (About), подгружается второй компонент. Это решение позволяет избежать ненужные загрузки.

const Home = React.lazy(() => import('./Home'));
const About = React.lazy(() => import('./About'));
function MyComponent() {
  return (
    <Suspense fallback={<div>Loading...</div>}>
      <Route path="/home" component={Home} />
      <Route path="/about" component={About} />
    </Suspense>
  );
}

Примечание: это простой пример, но что будет, когда у вас будут сотни элементов навигации и компонентов? Вы увидите большое различие в производительности.

Спасибо за прочтение!

Теги:
Хабы:
Всего голосов 3: ↑3 и ↓0+3
Комментарии8

Публикации

Истории

Работа

Ближайшие события