Рубрики
Без рубрики

Меньше – больше; Упростите свой код React, чтобы супер питание ваших приложений – Часть 2

Это вторая статья в серии, охватывающая различные стратегии, чтобы упростить ваш React Applicati … Tagged с JavaScript, WebDev, Tutorial, React.

Это вторая статья в серии, охватывающей различные стратегии для упрощения ваших приложений React.

Упростите компонент React

Есть ряд стратегий, которые мы можем принять, чтобы упростить наши компоненты без капризации существующих компонентов. Каждая стратегия будет рассмотрена в другом блоге.

  1. Отдельное состояние от дисплея, это поможет вашему приложению соответствовать хорошо установленным правилам MVC
  2. Отложить обработку на услуги и пользовательские крючки
  3. Избегайте перегрузки Использовать и USESTATE
  4. Определите, если Redux и Redux-saga действительно нужны
  5. Создать компоненты более высокого порядка для объединения функциональности между компонентами
  6. Shift Computational Logic Out из компонентов в вспомогательные функции, внедрение с помощью пользовательских крючков
  7. Используйте ленивую нагрузку и ленивое поведение, где это возможно

Отложить обработку на услуги и пользовательские крючки

React не хватает концепции услуг, в отличие от Angular, которая запекает в рамках, особенно с помощью инъекционных ресурсов. Как разработчики React, нам нужно выпекать эту функциональность в наших проектах. Услуги аккуратно инкапсулируют конкретную функциональность, становятся взаимозаменяемым ресурсом с помощью литья TypeScript и является еще одним шагом к смещению логики от уровня презентации.

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

const myComponent: React.FC = () => {
  const [ todos, setTodos ] = useState([]);
  useEffect(async () => {
    const result = await axios.get("https://jsonplaceholder.typicode.com/todos");
    const todos = res.data.filter(!!todos.completed));
    setTodos(todos);
  });

  return (
    
  )
}

Уровень поверхности это не похоже на то, что с этим компонентом не так много. Но что, если нам нужно начать обрабатывать ошибки из API, дополнительные проверки и манипуляции с данными? Наш Использоватьэффект Крюк внезапно становится перегруженным, раздутым поведением, которое может и должно быть отложено на услугу.

useEffect(async () => {
  try {
    const result = await axios.get("https://jsonplaceholder.typicode.com/todos");
    const todos = res.data.filter(!!todos.completed));
    setTodos(todos);
  } catch (e) {
    setLoaded(false);
    setErrorMessage("Could not load todos, please refresh your browser and make sure you're connected to the internet!");
  }
});

Чем больше мы добавляем к нашим Использоватьэффект Крюк, тем сложнее становится компонент, и тем сложнее он станет тестировать. Отложенный/асинхронный рендеринг уже затрудняет тестирование, с такими инструментами, как обновления Jest и Enzyme, но нелегко.

Мы можем упростить этот код, переведя обработку API на службу, позволяя нам последовательно выполнять запросы и последовательно обрабатывать ошибки, и разделить Использоватьэффект код в пользовательский крючок.

type Todo = { id: number, title: string };
type TodosService = {
  todos: async (completed?: boolean) => Promise>,
  todo: async (id: number) => Promise
};

class TodosServiceImpl implements TodosService {
  async todos(completed?: boolean): Promise> {
    try {
      const result = await axios.get("https://jsonplaceholder.typicode.com/todos");
      if (completed !== undefined) {
        return res.data.filter(todo => todo.completed === completed));
      }
      return res.data;
    } catch (e) {
      throw "Could not load todos, please refresh your browser and make sure you're connected to the internet!";
    }
  }

  async todo(id: number): Promise {
    try {
      const result = await axios.get(`https://jsonplaceholder.typicode.com/todos/${id}`);
      return res.data;
    } catch (e) {
      throw `Could not load todo ${id}, please refresh your browser and make sure you're connected to the internet!`;
    }
  }
}

В случае, если нам нужна взаимозаменяемая услуга, мы можем предоставить новую услугу, если она удовлетворяет контракту Todosservice :

const todosService: TodosService = {
  todos: async (completed?: boolean): Promise>  => {...}
  todo: async (id: number): Promise => {...}
}
// test of the implementation

Теперь, когда у нас есть внедрение услуг, мы можем потреблять ее в наших компонентах:

const todosService: TodosService = new TodosServiceImpl();

const useTodosLoader = (todosService: TodosService) => {
  const [ todos, setTodos ] = useState>([]);
  const [ hasError, setHasError ] = useState(false);
  const [ loaded, setLoaded ] = useState(false);

  useEffect(async () => {
    try {
      const list = await todosService.todos();
      setTodos(list);
      setLoaded(true);
    } catch (e) {
      setHasError(true);
    }
  }, []);

  return { todos, hasError, loaded };
}

const myComponent: React.FC<{ todosService: TodosService }> = ({ todosService }) => {
  const { todos, hasError, loaded } = useTodosLoaded(todosService);

  return (
    
  )
}

Все аспекты приведенного выше кода тестируемы – мы можем убедиться, что сервис называется, мы также можем проверить, что API называется. Мы можем проверить загрузку MyComponent Через ответы USETODOLOADER , и мы можем издеваться над поведением правильно. Несмотря на то, что мы, по крайней мере, удвоили объем кода для упрощения компонента, увеличение кода напрямую пропорционально простоте функционального кода и тестового кода.

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

const useMyState = () => {
  const [ myState, setMyState ] = useState(true);
  return { myState, setMyState }
}

const myComponent = () => {
  const { myState } = useMyState();
  ...
}

const myOtherComponent = () => {
  const { myState, setMyState } = useMyState();
  useEffect(() => {
    setTimeout(() => {setMyState(false)});
  }, []);
  ...
}

Мы также можем использовать крючки, чтобы подписаться на потоки событий. Это позволяет Mutliple не подключенные компоненты одновременно обновляться в зависимости от изменений состояния или движущихся событиями.

const myEventStream = () => {
  const [ myState, setMyState ] = useState(null);
  useEffect(() => {
    const subscription = observable.subscribe();
    subscription.next(event => setMyState(event.data));
    return () => subscription.unsubscribe();
  })

}

const myComponent = () => {
  const { myState } = useMyState();
  ...
}

const myOtherComponent = () => {
  const { myState } = useMyState();
  ...
}

observable.next({data: { foo: "bar"}});
// Updates myComponent
// Updates myOtherComponent

Следите за новостями, когда мы посмотрим на перегрузку Использоватьэффект и USESTATE Анкет

Оригинал: “https://dev.to/jmitchell38488/less-is-more-simplify-your-react-code-to-super-power-your-applications-part-2-4jam”