Блог Teacher Army

Написать статью

Подготовка к техническому собеседованию. Алгоритмическая секция, Two Pointers (два указателя) и О большое

Задачи алгоритмической секции собеседований в технологических компаниях часто становятся камнем преткновения для многих соискателей. Решение этих задач не только требует понимания основ алгоритмов, но и способностей к аналитическому мышлению и быстрому принятию решений. Наш друг Игорь Антонов записал отличное видео на эту тему. Я его посмотрел и хочу поделиться основными мыслями.

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

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

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

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

Как можно улучшить алгоритмическую сложность функции? Один из способов - использование метода "Two pointers". Этот подход особенно эффективен при работе с отсортированными массивами. Путем итерации по массиву с двумя указателями одновременно можно достичь линейной сложности.

Применение метода "Two pointers" можно наглядно продемонстрировать на примере задачи о возведении элементов отсортированного массива в квадрат и их сортировке по возрастанию. Два указателя могут перемещаться по массиву, возводить элементы в квадрат и сравнивать их. Это позволяет избежать шага сортировки и решить задачу за один проход, что соответствует линейной алгоритмической сложности.

Еще один пример применения метода "Two pointers" - это задача о проверке суммы элементов массива на равенство заданному значению. Путем итерации по массиву с двумя указателями можно эффективно решить эту задачу с линейной сложностью.

Для подготовки к алгоритмическим секциям собеседований рекомендуется решать задачи на специализированных платформах, таких как CodeWars или LeetCode. Это поможет улучшить навыки работы с алгоритмами разного уровня сложности и подготовиться к типичным задачам, которые могут встретиться на собеседованиях. Фокусируйтесь на задачах среднего уровня сложности, так как они наиболее представительны для типичных собеседований.

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

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

Если вам показалась интересной эта тематика, то рекомендую ознакомиться с оригинальным видео, который подготовил для вас Игорь. Не пожалеете!


Видео смотрел Олег Акинин

09.02.2024

Читать полностью

Как создать красивую прокрутку с 3D-анимацией, используя gsap и react-three-fiber

Сначала нам нужно создать новый проект реагирования. Для этого мы будем использовать Next.js 13, так как мы хотим использовать новый каталог приложений.

Чтобы установить следующий, нам нужно открыть наш терминал и ввести следующую команду:

npx create-next-app@latest

После этого нам нужно выбрать следующие варианты:

What is your project named? my-app
Would you like to add TypeScript with this project? N
Would you like to use ESLint with this project? Y
Would you like to use Tailwind CSS with this project? Y
Would you like to use the src/ directory with this project? N
What import alias would you like configured? @/

После завершения установки нам нужно установить несколько зависимостей, чтобы упростить жизнь:

npm i @react-three/drei @react-three/fiber gsap three framer-motion

react-three и drei - это пакеты, которые облегчают нам использование three.js в react-контексте.

После успешной установки пакетов мы можем запустить наш сервер разработки, введя npm run dev в консоли. Мы увидим, что по умолчанию next.js загружен. Сначала мы удалим весь шаблонный код next.js в page.js в каталоге приложений. Затем мы оптимизируем наш globals.css, чтобы он выглядел следующим образом:

@tailwind base;
@tailwind components;
@tailwind utilities;

:root {
  /* here come the vars: */
  --navigation-height: 4.8rem;
}

@media (prefers-color-scheme: dark) {
  :root {
    --foreground-rgb: 255, 255, 255;
    --background-start-rgb: 0, 0, 0;
    --background-end-rgb: 0, 0, 0;
  }
}

html,
body {
  width: 100%;
  height: 100%;
  margin: 0;
  padding: 0;
  background: black;
}

Затем мы очистим файл page.js от всего шаблонного кода и добавим следующий код:

"use client";

import { Inter } from "next/font/google";
import { Canvas } from "@react-three/fiber";

import ZeusModel from "@/components/ZeusModel";

import { skewRevealText } from "@/utils/gsap";
import { useLayoutEffect, useRef, useEffect } from "react";
import { useScroll } from "framer-motion";

export default function Home() {
  const { scrollYProgress, scrollY } = useScroll();
  const textRef = useRef();
  const textRefTwo = useRef();
  const textRefThree = useRef();
  const textRefFour = useRef();

  useLayoutEffect(() => {
    skewRevealText(textRef);
    skewRevealText(textRefTwo);
    skewRevealText(textRefThree);
    skewRevealText(textRefFour);
  }, []);

  return (
    <main>
      <div className="h-full w-full fixed top-0 left-0 ml-64 bg-hero-gradient bg-right bg-no-repeat bg-cover bg-blend-normal z-0">
        <Canvas>
          {/* <ambientLight intensity={0.03} /> */}
          <ZeusModel
            scale={0.1}
            position={[0, -2, 0]}
            rotation={[0, 5, 0]}
            scrollY={scrollY}
            scrollYProgress={scrollYProgress}
          />
        </Canvas>
      </div>
      <div className="max-w-7xl relative m-auto text-white  z-2">
        <div
          className="h-[100vh] flex items-center"
          initial="offscreen"
          whileInView="onscreen"
          viewport={{ once: true, amount: 0.2, margin: "800px" }}
        >
          <div className="overflow-hidden">
            <h1 className="text-8xl font-bold font-headline">
              Zeus the
              <br /> Greek God
            </h1>
            <p className="text-paragraph max-w-[307px]">
              Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam
              nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam
              erat, sed diam voluptua.
            </p>
          </div>
        </div>
        <div className="h-[100vh] flex items-center">
          <div className="overflow-hidden">
            <h2
              ref={textRef}
              className="text-5xl font-bold font-headline opacity-0"
            >
              Zeus
            </h2>
            <p
              className="text-paragraph max-w-[307px] opacity-0"
              ref={textRefThree}
            >
              Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam
              nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam
              erat, sed diam voluptua.
            </p>
          </div>
        </div>
        <div className="h-[100vh] flex items-center">
          <div className="overflow-hidden">
            <h2
              ref={textRefTwo}
              className="text-5xl font-bold font-headline opacity-0"
            >
              Zeus
            </h2>
            <p
              className="text-paragraph max-w-[307px] opacity-0"
              ref={textRefFour}
            >
              Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam
              nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam
              erat, sed diam voluptua.
            </p>
          </div>
        </div>
        <div className="h-[100vh] flex items-center"></div>
      </div>
    </main>
  );
}

Нам также нужно оптимизировать layout.js, чтобы у нас была навигация по каждой подстранице (хотя в настоящее время ее нет).

import Navigation from "@/components/Navigation";
import "./globals.css";
import { Inter, Bebas_Neue } from "next/font/google";

const bebasNeue = Bebas_Neue({ subsets: ["latin"], weight: "400" });

export default function RootLayout({ children }) {
  return (
    <html lang="en">
      <body className="p-5">
        <Navigation />
        {children}
      </body>
    </html>
  );
}

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

Наиболее важной частью здесь является компонент холста, предоставляемый тремя волокнами, которые содержат компонент Zeus.jsx. Мы создадим Zeus.jsx за несколько шагов, но это компонент, который содержит 3D-модель.

В качестве следующего шага мы создадим наши текстовые анимации. Для этого мы создадим каталог под названием utils и добавим туда новый файл под названием gsap.js.

Файл должен выглядеть следующим образом:

import { gsap } from "gsap";
import { ScrollTrigger } from "gsap/dist/ScrollTrigger";
/* reusable animations */

gsap.registerPlugin(ScrollTrigger);

export const skewRevealText = (textRef) => {
  ScrollTrigger.create({
    trigger: textRef.current,
    start: "center center",
    end: "center center",
    markers: false,
    once: true,
    onEnter: () => {
      gsap.fromTo(
        textRef.current,
        {
          y: 200,
          skewY: 10,
        },
        {
          duration: 0.6,
          y: 0,
          skewY: 0,
          opacity: 1,
        }
      );
    },
  });
};

Это просто оживляет текст и определенно может быть улучшено, так как основное внимание в этом уроке уделяется эффекту 3D-прокрутки.

Navigation.jsx, ZeusModel.jsx и Logo.jsx

Теперь пришло время создать новый каталог для хранения наших 3D-компонентов и именованных компоненты Navbar.

Там мы создадим два новых файла компонентов. Один будет называться ZeusModel.jsx, а другой - Navigation.jsx.

Я не буду объяснять стили попутного ветра, но некоторые из них имеют прямую связь с функциональностью прокрутки, поэтому будьте осторожны, вы их тоже добавляете.

// Navigation.jsx

import React from "react";
import Logo from "./svg/Logo";

function Navigation() {
  return (
    <nav className=" p-5 backdrop-blur-md fixed w-[642px] top-0 left-0 z-10 font-headline text-white">
      <div className="flex items-center w-full">
        <Logo />
        <div className="w-full pl-10">
          <ul className="flex w-full justify-around border-b-[1px] border-[#583922] pb-3 ">
            <li>Home</li>
            <li>Facts</li>
            <li>Content</li>
            <li>Design</li>
            <li>Love</li>
          </ul>
        </div>
      </div>
    </nav>
  );
}

export default Navigation;
export default ZeusModel;
import React from "react";

function Logo() {
  return (
    <svg
      width="66"
      height="65"
      viewBox="0 0 66 65"
      fill="none"
      xmlns="http://www.w3.org/2000/svg"
    >
      <path
        d="M30.9114 0.0151124C26.8768 0.253934 24.011 0.848448 20.7996 2.10353C15.9927 3.99379 11.7345 6.93586 8.3249 10.7418C1.92754 17.8658 -1.03995 27.6626 0.326927 37.1697C0.997661 41.8445 2.67958 46.2754 5.29136 50.2488C9.01599 55.9196 14.3819 60.2896 20.6471 62.7645C23.4825 63.8824 26.4652 64.5936 29.6665 64.9084C30.8911 65.0305 33.8992 65.0305 35.1339 64.9084C40.2102 64.4107 44.5598 63.0538 48.7623 60.6605C51.3333 59.2023 53.1271 57.8204 55.3578 55.5996C57.1257 53.8416 58.2592 52.5002 59.4582 50.7522C62.0448 46.9817 63.7674 42.749 64.6209 38.0437C64.941 36.2703 65.0018 35.3658 65.0018 32.5305C65.0018 29.7002 64.9207 28.5264 64.6007 26.7886C62.7051 16.5294 56.3838 8.05377 47.1462 3.39419C43.3403 1.46837 39.9409 0.502921 35.5862 0.106576C34.7783 0.0354377 31.6279 -0.0306195 30.9114 0.0151124ZM32.4409 0.670604C32.5577 0.828125 32.6492 1.79357 32.6898 3.33829C32.7051 3.96838 32.7305 4.59846 32.7457 4.73564L32.7711 4.98973L34.1736 5.08121C34.9459 5.13202 35.7844 5.19805 36.0384 5.23363C36.7854 5.32002 36.8413 5.31493 36.9226 5.14724C36.9633 5.07103 37.0496 4.71533 37.1157 4.35964C37.2986 3.37386 37.2783 3.23667 36.9531 3.23667C36.7244 3.23667 36.5415 3.31289 36.4805 3.43484C36.45 3.49073 36.3891 3.76005 36.3433 4.03444C36.2976 4.30883 36.2468 4.54765 36.2264 4.56289C36.2112 4.58322 35.947 4.57814 35.637 4.55273C34.3159 4.4511 33.7467 4.40029 33.5943 4.3698L33.4266 4.3444V3.67366C33.4266 3.30781 33.4622 2.47955 33.5028 1.83931C33.5435 1.19398 33.5791 0.650276 33.5791 0.629953C33.5791 0.584222 33.889 0.599464 35.2559 0.701093C37.1817 0.843367 40.3779 1.39723 40.7895 1.65638C40.8504 1.69703 40.7844 1.99682 40.4134 3.39927C39.758 5.87386 39.758 5.88913 39.8545 5.96534C39.946 6.03137 42.9236 7.02735 43.5232 7.18995L43.884 7.29156L44.1431 6.72754C44.5497 5.81796 44.6157 5.62487 44.5497 5.54357C44.5192 5.50803 44.3921 5.42673 44.2702 5.36574C43.9755 5.22854 43.9551 5.24885 43.6401 5.91453C43.5029 6.20415 43.3555 6.45315 43.3098 6.46837C43.2031 6.51414 40.8708 5.70617 40.7285 5.57406C40.6624 5.51816 40.9978 4.29866 41.4297 3.00801C41.7244 2.12894 41.8057 1.96634 41.9378 1.96634C42.4765 1.96634 48.1576 4.46635 48.4672 4.83731C48.5181 4.90334 48.447 5.05576 48.0303 5.79256C46.9531 7.68789 46.8261 7.92675 46.6584 8.30276C46.5669 8.51617 46.5009 8.70927 46.5161 8.72958C46.5263 8.75498 46.9328 9.02938 47.4157 9.34949C47.8984 9.66961 48.6501 10.2082 49.0974 10.5487C49.5395 10.8891 49.9208 11.1635 49.941 11.1533C49.9867 11.1381 50.7639 10.1727 50.9421 9.9186C51.125 9.64929 51.1301 9.5629 50.952 9.36472C50.6829 9.05478 50.566 9.1005 50.0631 9.72042C49.8496 9.98468 49.6564 10.1981 49.6309 10.1981C49.6106 10.1981 49.1332 9.8627 48.5789 9.44602C48.0251 9.03447 47.5171 8.6635 47.4511 8.61778L47.329 8.53648L47.9035 7.60154C48.6044 6.47346 49.326 5.37083 49.3717 5.37083C49.448 5.37083 50.5405 6.08727 51.1198 6.51918C52.8523 7.80477 55.0222 9.69501 55.0222 9.9186C55.0222 10.0355 54.5952 10.5131 53.325 11.8139L52.1208 13.0487L52.258 13.2113C52.9235 13.9989 53.7162 14.9593 54.1484 15.4979C54.4378 15.8536 54.7277 16.1788 54.7936 16.2245C54.9105 16.3008 54.9308 16.2957 55.1085 16.189C55.4591 15.9806 56.2467 15.3709 56.323 15.254C56.389 15.1575 56.389 15.1117 56.3381 15.0152C56.2519 14.8475 56.0841 14.6696 56.0082 14.6696C55.9724 14.6696 55.7386 14.8068 55.4898 14.9745C55.2456 15.1422 54.9968 15.2794 54.9412 15.2794C54.8342 15.2794 54.5651 15.0152 53.5791 13.9379C53.005 13.318 53.0149 13.3536 53.4113 12.881C53.6705 12.566 55.7386 10.5995 55.7843 10.6147C55.8046 10.6249 56.0487 10.884 56.3282 11.1889C57.2784 12.2407 58.3709 13.6839 59.306 15.1117C60.0733 16.2855 60.2307 16.5447 60.1746 16.6005C60.1491 16.626 59.306 17.1036 58.2997 17.6676C57.2935 18.2316 56.4503 18.7143 56.4248 18.7398C56.3942 18.7652 56.6482 19.3393 57.0955 20.2438C57.4919 21.0518 57.8883 21.8902 57.9849 22.1138C58.1979 22.6372 58.2639 22.6626 58.8436 22.4746C59.0769 22.3983 59.4379 22.2561 59.6463 22.1494C60.0068 21.9715 60.0275 21.9512 60.0426 21.7733C60.0525 21.6717 60.0224 21.5142 59.9766 21.4278C59.88 21.2398 59.8291 21.2449 59.2244 21.4786C58.6655 21.692 58.6353 21.692 58.4727 21.4532C58.3049 21.2042 57.6847 19.9948 57.4867 19.5223L57.3392 19.1767L57.4867 19.0599C57.8015 18.8058 60.4946 17.5152 60.7029 17.5152C60.8655 17.5152 62.1362 20.4573 62.7663 22.2916C63.0863 23.2164 63.2541 23.8313 63.2541 24.0701C63.2541 24.2733 63.2386 24.2784 61.6635 24.7357C60.1491 25.1727 59.8546 25.2642 59.4785 25.4319C59.1278 25.5843 59.1278 25.3912 59.4582 27.0172C59.5803 27.6473 59.7377 28.44 59.7985 28.7855C59.9564 29.6545 59.9361 29.6341 60.7491 29.6291C61.638 29.624 61.8822 29.502 61.8822 29.0498C61.8822 28.7347 61.8873 28.7347 61.12 28.7754L60.4239 28.8109L60.3933 28.6433C60.3019 28.2012 60.0577 26.6564 60.0374 26.4125C60.0224 26.2042 60.0374 26.1178 60.0987 26.0569C60.2509 25.9044 63.0962 25.2642 63.4625 25.2997C63.6147 25.315 63.6401 25.3404 63.6962 25.5386C63.9757 26.5192 64.4734 30.5894 64.4734 31.9258V32.6067H62.304L60.1289 32.6016L60.0935 32.9217C60.0323 33.4502 59.8037 35.8994 59.7683 36.4228L59.7325 36.9157L59.88 36.9461C60.1595 37.002 61.5367 37.1342 61.5975 37.1138C61.6328 37.0986 61.704 36.9563 61.7549 36.7988C61.8313 36.5498 61.8364 36.499 61.7705 36.438C61.7295 36.3974 61.4401 36.3211 61.1299 36.2652C60.8151 36.2144 60.5356 36.1534 60.505 36.1331C60.4442 36.0976 60.4593 35.7012 60.571 34.192L60.627 33.4095L62.4105 33.4298C63.7316 33.44 64.2246 33.4654 64.3108 33.5111C64.4126 33.567 64.4225 33.6128 64.4225 33.9532C64.4225 35.249 63.6859 40.0152 63.4012 40.5437C63.3508 40.6352 63.3149 40.6453 63.0152 40.6098C62.8323 40.5894 61.9481 40.3963 61.0536 40.1728C60.1543 39.9543 59.3616 39.7713 59.2857 39.7713C59.0873 39.7713 58.9605 39.9594 58.8078 40.4726C58.7314 40.7165 58.4826 41.4431 58.2488 42.0884C57.7511 43.4705 57.7205 43.5823 57.8425 43.7653C57.9387 43.9126 58.452 44.1667 59.0265 44.3496C59.4431 44.4817 59.5091 44.4665 59.6665 44.1972C59.8239 43.9279 59.7429 43.8415 59.0925 43.5569C58.7823 43.4248 58.5132 43.2978 58.5029 43.2775C58.4675 43.2216 59.0873 41.5447 59.2956 41.123C59.3922 40.9299 59.5091 40.7469 59.5548 40.7165C59.7023 40.625 62.0193 41.2602 62.6443 41.565C62.9336 41.7073 62.9746 41.748 62.9897 41.8852C63.0557 42.5356 60.4489 48.3588 60.0935 48.3588C59.9663 48.3588 59.7938 48.2674 58.2436 47.3931C56.3739 46.3313 56.2976 46.2958 56.2165 46.3822C56.0487 46.5651 53.9552 49.6747 53.9552 49.7511C53.9552 49.9189 54.7531 50.6607 55.1646 50.869C55.3729 50.9756 55.4643 50.9501 55.683 50.7215C55.896 50.5033 55.8758 50.4524 55.4747 50.1729C55.0731 49.8986 54.87 49.6851 54.87 49.548C54.87 49.4259 55.3526 48.6789 55.9828 47.8305L56.3433 47.3427L56.5365 47.4186C57.2223 47.7084 59.4276 49.0602 59.56 49.2784C59.6411 49.4108 58.9756 50.3911 57.5221 52.2665C56.2721 53.8821 55.3323 54.9643 55.19 54.9643C55.0477 54.9643 54.5193 54.5019 53.2133 53.2468L51.8974 51.9818L51.4143 52.4239C50.7489 53.0286 49.9104 53.7502 49.2751 54.2531C48.9857 54.4816 48.7415 54.69 48.7316 54.7154C48.7166 54.7559 49.2751 55.6759 49.5753 56.0926C49.6714 56.2297 49.7732 56.3362 49.8086 56.3362C49.9104 56.3362 50.4491 55.9757 50.4491 55.9045C50.4491 55.8692 50.4086 55.8079 50.3628 55.7726C50.2153 55.6505 49.687 54.9086 49.687 54.8224C49.687 54.7767 49.8086 54.6292 49.9561 54.492C50.3883 54.0853 51.7806 52.9268 51.8159 52.9423C51.8923 52.9777 53.7365 55.0105 54.123 55.4827C54.3567 55.7674 54.3666 55.7523 53.7822 56.2806C52.5983 57.3576 50.1239 59.1717 48.9654 59.8122C48.4013 60.127 48.4979 60.2236 47.3545 58.2418C46.8058 57.2916 46.3383 56.4838 46.318 56.4531C46.2621 56.3669 45.9775 56.4786 44.2295 57.2713C43.4521 57.6272 42.7153 57.942 42.5933 57.9726C42.3139 58.049 42.3088 58.1046 42.5222 58.7347C42.7813 59.502 42.9795 59.9389 43.0862 59.9696C43.2183 60.0153 43.5029 59.9135 43.6198 59.7867C43.7112 59.6849 43.7112 59.6698 43.5181 59.1109C43.4063 58.796 43.3301 58.501 43.3505 58.4604C43.386 58.3638 45.0934 57.4999 45.4897 57.3731C45.6421 57.3274 45.7997 57.302 45.8403 57.317C45.9165 57.3477 46.7753 58.9129 47.1664 59.7509C47.2937 60.0101 47.4054 60.3052 47.4256 60.4065C47.4563 60.5691 47.4407 60.6049 47.2937 60.7265C46.6838 61.2398 41.8464 63.1453 41.1045 63.1655C40.8453 63.1707 40.8199 63.1608 40.7183 63.0081C40.6573 62.9219 40.5303 62.5764 40.4439 62.246C39.8139 59.9493 39.6208 59.3649 39.4632 59.2786C39.3057 59.1971 37.9744 59.3753 35.6218 59.7966L35.2966 59.8527L35.327 60.0662C35.3423 60.1779 35.3931 60.6096 35.4388 61.0215C35.4846 61.4278 35.5405 61.7936 35.5608 61.8294C35.5964 61.8803 35.6573 61.8803 35.8758 61.819C36.2569 61.7177 36.2874 61.6361 36.1909 60.94C36.1502 60.6351 36.1299 60.3763 36.1451 60.3608C36.1705 60.3353 38.1167 59.9898 38.6655 59.9135L38.9043 59.8781L39.011 60.1628C39.2092 60.6963 39.8494 63.3281 39.7986 63.4097C39.7783 63.4403 39.6665 63.5063 39.5445 63.5572C38.8637 63.8617 35.4998 64.299 33.5028 64.3495L32.385 64.3801L32.4002 62.2766C32.4155 60.5846 32.4053 60.1576 32.3494 60.0917C32.2122 59.9239 28.2945 59.6698 28.1421 59.8221C28.0557 59.9088 27.9388 60.5337 27.9032 61.0974L27.8728 61.6211L28.0608 61.6974C28.4673 61.8699 28.5943 61.7125 28.7264 60.8792C28.7722 60.6049 28.8179 60.3711 28.828 60.3509C28.8484 60.3151 30.4947 60.4267 31.0892 60.5031C31.323 60.5337 31.5466 60.5846 31.5821 60.6148C31.6634 60.6808 31.6634 62.0071 31.5821 63.3739L31.5212 64.3396L31.2925 64.3547C30.2305 64.4362 25.4032 63.7042 24.514 63.3281L24.3158 63.2471L24.3514 62.993C24.3971 62.6678 24.8799 60.7166 25.1187 59.9187C25.3118 59.2584 25.3321 59.1212 25.2355 59.0397C25.2 59.0142 24.9561 58.928 24.6969 58.8568C24.4378 58.7805 23.5943 58.4911 22.827 58.2163C22.0597 57.9373 21.389 57.7082 21.3382 57.7082C21.2721 57.7082 21.1857 57.8152 21.0638 58.049C20.83 58.501 20.5709 59.1514 20.5709 59.3041C20.5709 59.5171 20.9672 59.7815 21.1451 59.6849C21.1908 59.6547 21.2874 59.4464 21.3585 59.2075C21.4296 58.9737 21.5313 58.7296 21.5821 58.6688L21.6736 58.5519L22.2122 58.6942C22.9033 58.8719 24.1228 59.2683 24.265 59.3597L24.3768 59.4361L24.199 60.1067C23.9856 60.9249 23.7721 61.6564 23.5384 62.419C23.3758 62.9473 23.3504 62.993 23.2386 62.993C23.076 62.993 21.8057 62.5406 20.5912 62.0481C19.0465 61.4278 16.8768 60.3353 16.6583 60.0714C16.5668 59.9644 16.6481 59.807 17.5831 58.1758C18.4113 56.7326 18.5587 56.4277 18.518 56.2604C18.4977 56.1736 18.0658 55.8437 17.0292 55.1019C15.2152 53.8161 15.3118 53.8821 15.1644 53.918C14.9459 53.9736 14.016 55.1778 14.016 55.4064C14.016 55.5591 14.3006 55.7014 14.4835 55.6302C14.5953 55.5897 14.9408 55.2438 15.2508 54.8728L15.388 54.7003L16.5313 55.503C17.1613 55.9451 17.6745 56.3315 17.6745 56.3617C17.6745 56.4329 17.0902 57.4339 16.328 58.6688L15.7284 59.634L15.012 59.1514C14.0465 58.4958 12.9438 57.6578 11.958 56.8396C11.0841 56.1077 10.0526 55.132 10.0526 55.0307C10.0526 54.9185 10.6522 54.2582 11.8615 53.0338L13.0455 51.8395L12.6593 51.4077C11.7294 50.361 10.8808 49.3698 10.5963 48.9838C10.4235 48.7552 10.266 48.5672 10.2406 48.562C10.1847 48.562 9.09729 49.3547 8.8991 49.5428C8.69078 49.7407 8.68569 49.8882 8.88897 50.1423L9.04648 50.3454L9.2243 50.2389C9.32088 50.1828 9.58 49.9948 9.80868 49.8274C10.144 49.5682 10.2253 49.5277 10.2761 49.5833C10.5048 49.8322 11.3483 50.8332 11.5871 51.1283C11.9276 51.56 11.9987 51.6872 11.958 51.8088C11.8818 52.053 10.0983 53.613 9.45807 54.0042L9.18368 54.1668L8.9245 53.918C8.07596 53.0894 5.58103 49.736 5.04745 48.6991L4.89503 48.4046L5.02205 48.3079C5.09322 48.257 5.66233 47.9116 6.29237 47.5406C7.62878 46.7632 8.44179 46.2551 8.52818 46.1484C8.60948 46.0519 8.5993 46.0315 7.80665 44.37C7.45599 43.6433 7.12066 42.9167 7.05458 42.7541C6.88689 42.3272 6.80054 42.3069 6.02816 42.5457C5.29136 42.7693 5.02205 42.9319 5.02205 43.1453C5.02205 43.3079 5.21006 43.5823 5.32185 43.5823C5.37775 43.5823 5.64706 43.501 5.91636 43.4045C6.18567 43.3079 6.44993 43.2266 6.50074 43.2266C6.57695 43.2266 6.67857 43.3994 6.94787 43.9482C7.29339 44.6698 7.66436 45.5895 7.66436 45.7368C7.66436 45.8435 6.37877 46.5854 5.01696 47.2663C4.47329 47.5406 4.4428 47.551 4.37166 47.4643C3.90418 46.8395 1.77002 41.4685 1.77002 40.9095C1.77002 40.6656 2.04441 40.5539 4.0058 40.0254C5.60643 39.5935 5.94686 39.4766 5.91636 39.375C5.87574 39.2327 5.64706 38.0285 5.40824 36.7124C5.28123 36.0163 5.15416 35.4065 5.11862 35.3455C5.07286 35.254 5.03223 35.2439 4.87981 35.2744C4.77306 35.2896 4.3869 35.3252 4.02104 35.3404C3.65011 35.3608 3.3249 35.4014 3.29442 35.4319C3.21312 35.5132 3.17755 35.9197 3.23852 36.0721C3.30458 36.2449 3.43669 36.2551 4.15316 36.1382C4.41739 36.0925 4.63589 36.0671 4.64605 36.0721C4.68162 36.1128 5.02714 38.1657 5.05764 38.5112L5.08813 38.9025L4.94075 38.9583C4.58507 39.0955 1.88181 39.6697 1.59218 39.6697C1.42449 39.6697 1.42449 39.6697 1.34319 39.3039C1.0942 38.1504 0.753758 35.5234 0.652134 33.9278C0.626725 33.4654 0.586075 32.937 0.570832 32.7439L0.540343 32.4034H2.75072H4.96615L4.99156 32.1341C5.00683 31.9919 5.06782 31.3567 5.12876 30.7266C5.18465 30.0965 5.27613 29.2429 5.33203 28.8262C5.38793 28.4095 5.42347 28.064 5.41842 28.0589C5.38284 28.0233 4.10234 27.8811 3.8432 27.8811C3.44686 27.8811 3.31474 28.003 3.34015 28.3485C3.35031 28.4908 3.63995 28.6026 4.10234 28.6534C4.34117 28.6738 4.55967 28.7195 4.58507 28.7449C4.67654 28.8364 4.67145 29.3801 4.56983 30.4929C4.51394 31.1026 4.45804 31.6108 4.44788 31.6209C4.43772 31.6311 3.80255 31.6158 3.03527 31.5904C1.63283 31.5396 0.799489 31.4736 0.692784 31.4075C0.484446 31.2754 1.17551 26.001 1.59218 24.5376C1.6684 24.2886 1.67856 24.2733 1.84116 24.2733C2.08506 24.2733 2.79645 24.4258 4.07186 24.7561C4.68162 24.9136 5.37266 25.0813 5.60643 25.1321L6.03325 25.2286L6.21107 24.7103C6.31274 24.4309 6.61254 23.5823 6.87675 22.8303C7.14097 22.0731 7.35947 21.4329 7.35947 21.3973C7.35947 21.2195 6.10946 20.5081 5.76903 20.4928C5.63692 20.4877 5.59625 20.5182 5.49463 20.691C5.31676 21.006 5.33712 21.0975 5.62165 21.2042C5.75376 21.2499 6.03325 21.3567 6.25175 21.438L6.63794 21.5853L6.26697 22.6626C6.06374 23.2571 5.85033 23.8516 5.79953 23.9939L5.70295 24.2479L5.44383 24.2428C5.28122 24.2378 4.56983 24.0548 3.56373 23.7601C2.67449 23.501 1.94278 23.2825 1.93262 23.2774C1.9123 23.2672 2.49157 21.6819 2.78628 20.9349C3.17247 19.9745 3.50275 19.2377 4.05661 18.0995C4.67145 16.8394 4.82896 16.6005 5.02205 16.6005C5.11353 16.6005 5.65215 16.88 6.49565 17.3627C8.081 18.2723 8.56881 18.5314 8.6806 18.5314C8.7924 18.5314 9.25989 17.8963 10.2761 16.3871C10.9469 15.3861 11.079 15.1676 11.0485 15.0609C11.0129 14.9186 10.1847 14.2326 9.83918 14.0548C9.63081 13.9481 9.54442 13.9633 9.37168 14.1564C9.21921 14.3241 9.30561 14.4715 9.79341 14.9186L10.2507 15.3353L9.91539 15.8282C9.40727 16.5701 8.80767 17.378 8.68569 17.4847C8.5739 17.5863 8.5739 17.5863 8.30459 17.4542C7.70499 17.1595 5.65724 15.8282 5.56066 15.6707C5.48954 15.5589 5.61656 15.315 6.13486 14.5426C7.02408 13.2215 8.28428 11.6615 9.32088 10.6097L10.0424 9.87288L11.4042 11.1991C12.1562 11.9308 12.8829 12.6168 13.0201 12.7286L13.269 12.9369L13.6552 12.5609C14.0414 12.1899 14.6207 11.6869 15.7792 10.7164C16.1197 10.4318 16.4093 10.1777 16.4246 10.1523C16.4805 10.0609 15.5048 8.81088 15.2864 8.69908C15.1644 8.6381 15.1288 8.6381 14.9764 8.71431C14.6766 8.86678 14.7071 9.05987 15.1237 9.62389C15.2863 9.84239 15.4337 10.0456 15.454 10.0812C15.4744 10.1168 15.0831 10.4979 14.4124 11.0873L13.33 12.0375L13.0505 11.7326C12.8981 11.5649 12.3391 10.9704 11.8056 10.4064C11.2772 9.84239 10.8148 9.33427 10.7741 9.27837C10.7131 9.18689 10.7284 9.16149 10.957 8.95317C12.1257 7.9013 13.9042 6.52936 15.1593 5.70112C16.0587 5.11166 16.4347 4.90334 16.5719 4.92365C16.6532 4.93383 16.9276 5.35556 17.705 6.66656C18.2741 7.61677 18.767 8.43996 18.8077 8.49586C18.8788 8.59238 18.9195 8.57716 20.0932 8.01309C20.7589 7.69807 21.5973 7.29665 21.948 7.12387C22.3036 6.94604 22.6238 6.79358 22.6593 6.78344C22.7508 6.75295 22.6797 6.46837 22.3951 5.74684C22.1258 5.05576 22.0394 4.94401 21.7803 4.97955C21.6736 4.99482 21.5262 5.04563 21.4551 5.09134C21.3128 5.18282 21.3077 5.15742 21.5618 5.85355C21.6532 6.10254 21.7447 6.36167 21.765 6.42774C21.7955 6.53445 21.7447 6.57003 21.0689 6.89015C20.6674 7.08324 20.1187 7.33219 19.8493 7.44398L19.3514 7.65235L19.2294 7.48975C18.8788 7.03244 17.6491 4.80172 17.5932 4.52224C17.5678 4.37997 17.5831 4.35456 17.8016 4.20212C18.5841 3.6635 23.01 1.86979 23.7772 1.77833C24.3209 1.71227 24.4276 1.86471 24.7376 3.08423C25.2711 5.18791 25.4439 5.72653 25.6319 5.79765C25.7183 5.83323 29.4073 5.20823 29.636 5.11675C29.7732 5.06594 29.7732 5.06594 29.7427 4.67468C29.6665 3.78545 29.5699 3.26716 29.4581 3.17569C29.3311 3.06899 29.1228 3.09947 28.9957 3.24683C28.9195 3.33321 28.9043 3.45516 28.9043 4.00395V4.65436L28.7417 4.68485C28.6502 4.70009 28.1167 4.79663 27.5577 4.89825C26.9988 4.99991 26.4601 5.08625 26.3636 5.08625L26.1857 5.09134L25.9723 4.45619C25.7081 3.64825 25.3931 2.30679 25.3626 1.8139C25.3372 1.4328 25.3372 1.42772 25.4744 1.36674C25.9418 1.15333 28.4571 0.782394 30.3525 0.650276C30.7742 0.619792 31.2163 0.584222 31.3433 0.574056C31.7955 0.533405 32.3799 0.589303 32.4409 0.670604Z"
        fill="#F2F2F2"
      />
      <path
        d="M11.3774 39.6467L17.1463 25.4508H11.6602V22.6229H20.4832V25.3942L14.7143 39.5901H20.4832V42.418H11.3774V39.6467ZM22.2451 22.6229H30.7287V25.4508H25.3557V30.6823H29.6258V33.5102H25.3557V39.5901H30.7287V42.418H22.2451V22.6229ZM37.0428 42.7008C35.5346 42.7008 34.3846 42.2766 33.5928 41.4282C32.801 40.561 32.4051 39.3262 32.4051 37.7237V22.6229H35.5157V37.95C35.5157 38.6286 35.6477 39.1188 35.9116 39.4204C36.1944 39.7221 36.5903 39.8729 37.0993 39.8729C37.6083 39.8729 37.9948 39.7221 38.2587 39.4204C38.5415 39.1188 38.6829 38.6286 38.6829 37.95V22.6229H41.6805V37.7237C41.6805 39.3262 41.2846 40.561 40.4928 41.4282C39.701 42.2766 38.551 42.7008 37.0428 42.7008ZM47.9398 42.7008C46.4316 42.7008 45.291 42.2766 44.518 41.4282C43.7451 40.561 43.3586 39.3262 43.3586 37.7237V36.5926H46.2996V37.95C46.2996 39.2319 46.8369 39.8729 47.9116 39.8729C48.4394 39.8729 48.8353 39.7221 49.0993 39.4204C49.3821 39.1 49.5234 38.5909 49.5234 37.8934C49.5234 37.0639 49.3349 36.3381 48.9579 35.7159C48.5808 35.075 47.8833 34.3114 46.8652 33.4254C45.5832 32.2942 44.6877 31.2762 44.1787 30.3713C43.6697 29.4475 43.4152 28.4106 43.4152 27.2606C43.4152 25.6959 43.8111 24.4893 44.6029 23.641C45.3947 22.7738 46.5447 22.3401 48.053 22.3401C49.5423 22.3401 50.664 22.7738 51.4181 23.641C52.1911 24.4893 52.5775 25.7147 52.5775 27.3172V28.1373H49.6366V27.1192C49.6366 26.4406 49.5046 25.9504 49.2407 25.6487C48.9767 25.3283 48.5902 25.168 48.0812 25.168C47.0443 25.168 46.5258 25.7996 46.5258 27.0627C46.5258 27.7791 46.7143 28.4483 47.0914 29.0705C47.4874 29.6926 48.1943 30.4467 49.2124 31.3328C50.5132 32.4639 51.4087 33.4914 51.8988 34.4151C52.389 35.3389 52.6341 36.4229 52.6341 37.6672C52.6341 39.2885 52.2288 40.5327 51.4181 41.3999C50.6263 42.2672 49.4669 42.7008 47.9398 42.7008Z"
        fill="#F2F2F2"
      />
    </svg>
  );
}

export default Logo;
// Zeus.jsx

"use client";

import React, { useEffect } from "react";
import { useGLTF } from "@react-three/drei";
import { useFrame } from "@react-three/fiber";
import * as THREE from "three";

function ZeusModel({ position, scale, rotation, scrollYProgress }) {
  const axesHelper = new THREE.AxesHelper(5);
  const { scene } = useGLTF("./3dmodels/zeus_fix.glb");
  useFrame((state, delta) => {
    //console.log(-2 * (scrollYProgress.current * 0.3));
    scene.add(axesHelper);
    state.scene.rotation.set(
      0,
      Math.atan(scrollYProgress.current * Math.PI * 2) * 4,
      0
    );
    state.scene.position.set(0, -2 * (scrollYProgress.current * 0.3), 0);
    state.camera.position.set(0, 0, 2 - scrollYProgress.current * 1);
    state.camera.lookAt(0, 0, 0);
  });
  return (
    <>
      <primitive
        object={scene}
        scale={scale}
        position={position}
        rotation={rotation}
      />
    </>
  );
}

Вам нужно скачать модель zeus_fix.glb, используя эту ссылку. Он был сделан LZ Creation и также доступен на sketchfab, но позиции не являются нулевыми, поэтому сначала вам нужно будет отредактировать его с помощью блендера. Чтобы избавить вас от этого, я загрузил исправленный файл, готовый к использованию, на megaupload.

Затем внутри общей папки нам нужно создать подпапку 3dmodels. Там мы разместим файл zeus_fix.glb.

Нам нужно использовать каталог "использовать клиент", предоставляемый nextjs, чтобы модель была отображена на клиенте.

В компоненте Zeus.jsx мы используем useFrame-Hook, предоставляемый трехволокном, для анимации свойства вращения моделей на каждом кадре, связанном с реквизитом scrollYProgress. Если значение scrollYProgress изменится, для камеры будет рассчитано новое значение вращения и положения, поэтому сцена изменится.

В настоящее время мы используем framer-motions useScroll Hook в нашем файле page.js, чтобы получить прогресс прокрутки страницы, так как он очень прост и удобен в использовании.

// excerpt from the page.js file, no need to change something, 
// this code is already entirely contained in the file

import { useScroll } from "framer-motion";

export default function Home() {
  const { scrollYProgress, scrollY } = useScroll();
//...
}

scrollYProgress возвращает значение от 0 до 1, где 0 обозначает начало нашей страницы и 1 - конец. В основном это обеспечило процент нашей позиции прокрутки для всей страницы.

Конфигурация Tailwind

И последнее, но не менее важное: нам нужно добавить некоторые опции в нашу конфигурацию попутного ветра, чтобы получить фон.

/** @type {import('tailwindcss').Config} */
module.exports = {
  content: [
    "./pages/**/*.{js,ts,jsx,tsx,mdx}",
    "./components/**/*.{js,ts,jsx,tsx,mdx}",
    "./app/**/*.{js,ts,jsx,tsx,mdx}",
  ],
  theme: {
    extend: {
      fontFamily: {
        headline: ["Bebas Neue", "sans serif"],
        paragraph: ["Inter", "sans serif"],
      },
      backgroundImage: {
        "hero-gradient": `
          url('/img/Binary_001.png'),
          linear-gradient(115.68deg, #000000 25.29%, #2B2B2B 94.75%);`,

        "hero-background": 'url("/img/Binary_001.png")',
      },
    },
  },
  plugins: [],
};

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

Шрифт можно загрузить из Google, если вы также хотите его использовать.

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


Если вы хотите освоить искусство создания анимаций и ищете квалифицированного наставника, Teacher Army может предложить вам свою помощь. Пройдите по ссылке и оставьте заявку и мы подберем для вас опытного ментора по программированию.
В индивидуальной консультации он сможет подробно объяснить вам любую тему, связанную с созданием анимаций. Не упустите возможность получить профессиональное руководство и достичь ваших целей в этой увлекательной области!

Оригинальная статья

Перевела Дарья Крещёнова

11.12.2023

Читать полностью

Как обновить NPM зависимости

Менеджер пакетов Node (npm) предоставляет различные функции, помогающие вам устанавливать и поддерживать зависимости вашего проекта.

Зависимости могут устаревать со временем из-за исправлений ошибок, новых функций и других обновлений. Чем больше у вас зависимостей проекта, тем сложнее следить за обновлениями.

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

Как поддерживать зависимости в актуальном состоянии

Теперь вы можете по очереди просматривать каждый отдельный пакет в package.json, чтобы изменить версию и запустить npm install <package>@latest, чтобы получить последнюю версию. Но это будет не самый эффективный метод.

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

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

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

В этой статье я подробно рассмотрю методы проверки и обновления зависимостей.

Как использовать команду npm outdated

npm outdated

Эта команда проверит каждую установленную зависимость и сравнит текущую версию с последней версией в реестре npm. Результат будет выведен в виде таблицы с указанием доступных версий.

Она встроена в npm, поэтому не требуется скачивать дополнительные пакеты. npm outdated - это хорошее место для начала, чтобы получить представление о количестве необходимых обновлений зависимостей.

  • Current - текущая установленная версия.
  • Wanted - максимальная версия пакета в соответствии с диапазоном semver.
  • Latest - версия пакета, помеченная как последняя в реестре npm.

С помощью этого метода для установки обновлений для каждого пакета достаточно выполнить:

npm update

Помните, что при использовании npm update никогда не произойдет обновление до версии, содержащей серьезные изменения. Он обновляет зависимости в package.json и package-lock.json. Будет использоваться "желаемая" версия.

Для получения "последней" версии добавьте @latest к отдельным установкам, например, npm install react@latest.

Как использовать npm-check-updates

Для более продвинутого и настраиваемого обновления я бы рекомендовал использовать npm-check-updates. Этот пакет может делать все то же самое, что и npm outdated и npm upgrade, с некоторыми дополнительными опциями настройки. Однако он требует установки пакета.

Чтобы начать работу, установите пакет npm-check-updates глобально:

npm install -g npm-check-updates

Затем запустите ncu, чтобы отобразить пакеты для обновления. Как и npm outdated, он не будет применять никаких изменений.

ncu
## Проверка package.json
[====================] 12/12 100%

@testing-library/user-event ^13.5.0 → ^14.2.1
@types/jest ^27.5.2 → ^28.1.4
@types/node ^16.11.42 → ^18.0.1

## Запустите ncu -u для обновления package.json

Чтобы обновить зависимости, вам нужно просто выполнить:

ncu --upgrade

## или
ncu -u
  • Красный = мажор
  • Голубой = минор
  • Зеленый = патч

Это обновляет зависимости только в файле package.json и выбирает последнюю версию, даже если она содержит разрушающие изменения. При использовании этого метода npm install не запускается автоматически, поэтому обязательно запустите его после обновления package-lock.json.

Чтобы выбрать желаемый тип версии, выполните ncu --target [patch, minor, latest, newest, greatest].

Как использовать интерактивный режим с npm-check-updates

ncu --interactive

## или
ncu -i

Интерактивный режим позволяет выбрать определенные пакеты для обновления. По умолчанию выбираются все пакеты.

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

Есть несколько способов повысить интерактивность npm-check-updates.

ncu --interactive --format group

Эта команда группирует и упорядочивает пакеты по основным, второстепенным и патч-релизам.

npm-check-updates предоставляет другие полезные инструменты, такие как режим доктора, который устанавливает обновления и запускает тесты для проверки на наличие неработающих изменений.

Я настоятельно рекомендую ознакомиться с документацией, чтобы узнать больше обо всем, что может предложить этот пакет. Проект хорошо поддерживается, и на момент написания этой статьи еженедельная скорость загрузки составляла ~294,467.

Резюме

Регулярное обновление зависимостей поможет повысить безопасность и производительность ваших приложений.

npm outdated и npm-check-updates - полезные инструменты для проверки пакетов, которым не помешает обновление версии.

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

Надеюсь, эти методы помогут вам на пути к обновлению!


Если вы сталкиваетесь с трудностями в работе с NPM и ищете профессиональную помощь, Teacher Army может быть вашим идеальным партнером. Просто перейдите по ссылке и оставьте заявку, чтобы мы могли подобрать для вас опытного ментора по программированию.
Наш ментор проведет с вами индивидуальную консультацию, где сможет подробно объяснить любую тему, связанную с управлением зависимостями. Мы готовы помочь вам достичь ваших целей в любой области программирования!

Оригинальная статья

Перевела Дарья Крещёнова

04.12.2023

Читать полностью

Введение в SWR: React Hooks для удаленной выборки данных

В этой статье мы рассмотрим новый способ получения данных в React Apps под названием SWR. Это набор хуков для удаленного получения данных, который упрощает такие вещи, как кэширование, пагинация и так далее. Мы также создадим приложение Pokedex с нуля и используем возможности SWR для получения данных и их постраничной публикации.


SWR - это легкая библиотека, созданная компанией Vercel (ранее ZEIT), которая позволяет получать, кэшировать или повторно получать данные в реальном времени с помощью React Hooks. Она построена с использованием React Suspense, который позволяет вашим компонентам "ждать" чего-то, прежде чем они смогут отобразиться, включая данные. SWR поставляется с такими замечательными функциями, как зависимая выборка, фокус на переоценке, восстановление позиции прокрутки и так далее. Это также очень мощный инструмент, поскольку он не зависит от бэкенда и имеет хорошую поддержку TypeScript. Это пакет, у которого большое будущее.

Почему вас это должно волновать? Это должно вас заинтересовать, если вы искали библиотеку, которая позволяет не только получать данные из API, но и делать такие вещи, как кэширование и зависимая выборка. То, что будет рассмотрено в этом руководстве, пригодится вам при создании приложений React с большим количеством подвижных частей. Предполагается, что вы уже использовали Axios и Fetch API, хотя мы и сравним, чем они отличаются от SWR, мы не будем вдаваться в подробности их реализации.

В этом руководстве я познакомлю вас с React Hooks for Remote Data Fetching на примере создания приложения Pokedex, которое запрашивает данные из Pokemon API. Мы также погрузимся в другие возможности, которые предоставляет SWR, выделим его отличия от таких популярных решений, как Fetch API и библиотека Axios, и расскажем вам о причинах использования этой библиотеки и о том, почему вам стоит обратить внимание на SWR.

Итак, давайте начнем с ответа на фундаментальный вопрос: Что такое SWR?

Что такое SWR?

SWR - это аббревиатура от stale-while-revalidate. Это библиотека React Hooks для удаленной выборки данных. SWR работает в три основных этапа: сначала он возвращает данные из кэша (устаревшая часть), затем отправляет запрос на выборку (часть, связанная с перепроверкой) и, наконец, приходит с актуальными данными. Но не беспокойтесь, SWR обрабатывает все эти шаги за нас. Единственное, что нам нужно сделать, это передать хуку useSWR необходимые параметры для выполнения запроса.

SWR также обладает некоторыми приятными особенностями, такими как:

  • Независимость от бэкенда
  • Быстрая навигация по странице
  • Переоценка по фокусу
  • Интервальный опрос
  • Дедупликация запросов
  • Локальная мутация
  • Пагинация
  • TypeScript готов
  • Поддержка SSR
  • Режим приостановки
  • Поддержка React Native
  • Легкий вес.

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

Важно знать, что название пакета - swr или SWR, а хук, используемый для получения возможностей SWR, называется useSWR.

Теоретически, SWR - это то, что вам нужно, чтобы улучшить выборку данных. Однако у нас уже есть два отличных способа выполнения HTTP-запросов в нашем приложении: Fetch API и библиотека Axios.

Итак, зачем использовать новую библиотеку для получения данных? Попробуем ответить на этот закономерный вопрос в следующем разделе.

Сравнение с Fetch и Axios

В наших приложениях React уже есть множество способов выполнения HTTP-запросов, и два из самых популярных - это API Fetch и библиотека Axios. Они оба великолепны и позволяют нам легко получать или отправлять данные. Однако, как только операция будет выполнена, они не помогут нам кэшировать или пагинации данных, вы должны сделать это самостоятельно.

Axios или Fetch просто обработают запрос и вернут ожидаемый ответ, не более того.

И по сравнению с SWR, это немного другое, потому что SWR под капотом использует Fetch API для запроса данных с сервера - это своего рода слой, построенный поверх него. Тем не менее, он обладает некоторыми хорошими функциями, такими как кэширование, пагинация, восстановление позиции прокрутки, зависимая выборка и т.д., и, если быть точным, определенным уровнем реактивности из коробки, которого нет у Axios или Fetch. Это большое преимущество, потому что наличие таких возможностей помогает сделать наши React-приложения быстрыми и удобными в использовании и заметно уменьшить размер кода.

И в заключение, просто помните, что SWR - это не то же самое, что Axios или Fetch, даже если они помогают работать с HTTP-запросами. SWR более продвинут, чем они, он обеспечивает некоторые улучшения для синхронизации нашего приложения с back-end и, следовательно, увеличивает производительность нашего приложения.

Теперь мы знаем, какие отличия имеет SWR по сравнению с библиотекой Axios или Fetch API, пришло время разобраться, зачем использовать такой инструмент.

Рекомендуем прочитать: Потребление REST API в React с помощью Fetch и Axios

Почему стоит использовать SWR для получения данных?

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

Обычно при получении данных с сервера мы показываем пользователю сообщение о загрузке или спиннер. А с помощью SWR вы можете сделать это лучше, показывая пользователю кэшированные или устаревшие данные во время получения новых данных из API. И как только эта операция будет выполнена, он проведет ревалидацию данных, чтобы показать новую версию. И вам не нужно ничего делать, SWR будет кэшировать данные при первом получении и автоматически извлекать их при новом запросе.

Итак, мы уже видим, почему использование SWR вместо Axios или Fetch лучше, в зависимости от того, что именно вы хотите построить. Но для многих случаев я рекомендую использовать SWR, потому что у него есть отличные возможности, которые выходят за рамки простого получения и возврата данных.

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

Итак, давайте начнем с создания нового проекта.

Настройка

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

Чтобы создать новое приложение, нам нужно выполнить следующую команду в терминале:

npx create-react-app react-swr

Далее нам нужно установить библиотеку SWR, сначала перейдя в папку с приложением React.

cd react-swr

И выполните в терминале следующую команду для установки пакета SWR.

yarn add swr

Или если вы используете npm:

npm install swr

Теперь у нас все готово, давайте структурируем проект следующим образом, чтобы начать использовать SWR:

src
├── components
| └── Pokemon.js
├── App.js
├── App.test.js
├── index.js
├── serviceWorker.js
├── setupTests.js
├── package.json
├── README.md
├── yarn-error.log
└── yarn.lock

Как вы можете видеть, структура папок проста. Единственное, на что следует обратить внимание, это папка components, в которой находится файл Pokemon.js. Он будет использоваться позже в качестве презентационного компонента для показа одного покемона, когда мы получим данные от API.

Отлично! Теперь, когда все готово, мы можем начать получать данные из API с помощью useSWR.

Получение удаленных данных

Пакет SWR имеет несколько удобных функций, как мы видели выше. Однако существует два способа настройки этой библиотеки: локально или глобально.

Локальная настройка означает, что каждый раз, когда мы создаем новый файл, нам придется заново настраивать SWR, чтобы иметь возможность получать удаленные данные. А глобальная настройка позволяет нам повторно использовать часть нашей конфигурации в разных файлах, поскольку функция fetcher может быть объявлена один раз и использоваться везде.

И не беспокойтесь, мы рассмотрим оба варианта в этой статье, а пока давайте запачкаем руки и добавим немного осмысленного кода в файл App.js.

Отображение данных

import React from 'react'
import useSWR from 'swr'
import { Pokemon } from './components/Pokemon'

const url = 'https://pokeapi.co/api/v2/pokemon'

const fetcher = (...args) => fetch(...args).then((res) => res.json())

function App() {
  const { data: result, error } = useSWR(url, fetcher)

  if (error) return <h1>Something went wrong!</h1>
  if (!result) return <h1>Loading...</h1>

  return (
    <main className='App'>
      <h1>Pokedex</h1>
      <div>
        {result.results.map((pokemon) => (
          <Pokemon key={pokemon.name} pokemon={pokemon} />
        ))}
      </div>
    </main>
  )
}

export default App

Как вы видите, мы начинаем с импорта useSWR из библиотеки SWR. Здесь объявляется URL API, из которого вы хотите получить данные, и функция для получения этих данных.

Функция fetcher используется здесь для преобразования данных в JSON. Она получает полученные данные в качестве аргумента и возвращает что-то.

Обратите внимание, что здесь я использую оператор Rest ((...args)), поскольку я не уверен в типе и длине данных, полученных в качестве параметра, поэтому я копирую все, прежде чем передать их снова в качестве аргумента методу fetch, предоставляемому useSWR, который преобразует данные в JSON и возвращает их.

Таким образом, fetcher и url API теперь можно передавать в качестве параметров хуку useSWR. Теперь он может выполнить запрос и вернуть два состояния: полученные данные и состояние ошибки. А data: result - это то же самое, что и data.result, мы используем деструктуризацию объекта для извлечения результата из данных.

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

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

Создание компонента pokemon

import React from 'react'
import useSWR from 'swr'

const fetcher = (...args) => fetch(...args).then((res) => res.json())

export const Pokemon = ({ pokemon }) => {
  const { name } = pokemon
  const url = 'https://pokeapi.co/api/v2/pokemon/' + name

  const { data, error } = useSWR(url, fetcher)

  if (error) return <h1>Something went wrong!</h1>
  if (!data) return <h1>Loading...</h1>

  return (
    <div className='Card'>
      <span className='Card--id'>#{data.id}</span>
      <img
        className='Card--image'
        src={data.sprites.front_default}
        alt={name}
      />
        <h1 className='Card--name'>{name}</h1>
        <span className='Card--details'>
          {data.types.map((poke) => poke.type.name).join(', ')}
        </span>
    </div>
  )
}

Здесь у нас есть компонент, который получает данные об одном покемоне от API и отображает их. Однако полученные данные не содержат всех необходимых полей, поэтому мы должны сделать еще один запрос к API, чтобы получить полный объект покемона.

Как видите, мы используем тот же процесс для получения данных, даже если на этот раз мы добавим имя покемона к URL.

Кстати, если вы не знакомы с деструктуризацией, ({ pokemon }) - это то же самое, что получение реквизита и доступ к объекту pokemon с помощью props.pokemon. Это просто сокращение для извлечения значений из объектов или массивов.

После этого, если вы перейдете в корневую папку проекта и выполните в терминале следующую команду:

yarn start

Или если вы используете npm:

npm start

Отлично! Теперь мы можем получать удаленные данные с помощью SWR. Однако эта настройка является локальной и может быть немного избыточной, поскольку вы уже видите, что App.js и Pokemon.js используют одну и ту же функцию fetcher для выполнения одних и тех же действий.

Но, к счастью, пакет поставляется с удобным провайдером SWRConfig, который помогает настроить SWR глобально. Это компонент-обертка, который позволяет дочерним компонентам использовать глобальную конфигурацию и, следовательно, функцию fetcher.

Чтобы настроить SWR глобально, нам нужно обновить файл index.js, поскольку именно в нем компонент App отображается с помощью React DOM. Если хотите, вы можете использовать SWRConfig непосредственно в файле App.js.

Настройка swr глобально

import React from 'react'
import ReactDOM from 'react-dom'
import { SWRConfig } from 'swr'
import App from './App'
import './index.css'

const fetcher = (...args) => fetch(...args).then((res) => res.json())

ReactDOM.render(
  <React.StrictMode>
    <SWRConfig value={{ fetcher }}>
      <App />
    </SWRConfig>
  </React.StrictMode>,
  document.getElementById('root')
)

Как вы видите, мы начинаем с импорта SWRConfig, который является провайдером, который должен обернуть высший компонент или просто часть вашего приложения React, которая должна использовать функции SWR. Он принимает в качестве props значение, которое ожидает объект config. Вы можете передать более одного свойства объекту config, здесь мне нужна только функция для получения данных.

Теперь, вместо того чтобы объявлять функцию fetcher в каждом файле, мы создадим ее здесь и передадим ее в качестве значения в SWRConfig. Таким образом, мы можем получать данные на любом уровне нашего приложения без создания еще одной функции и, следовательно, избежать избыточности.

Кроме того, fetcher равнозначен fetcher: fetcher, это просто синтаксический сахар, предложенный ES6. С этим изменением нам нужно обновить наши компоненты для использования глобальной конфигурации.

Используя глобальную конфигурацию swr

import React from 'react'
import useSWR from 'swr'
import { Pokemon } from './components/Pokemon'

const url = 'https://pokeapi.co/api/v2/pokemon'

function App() {
  const { data: result, error } = useSWR(url)

  if (error) return <h1>Something went wrong!</h1>
  if (!result) return <h1>Loading...</h1>

  return (
    <main className='App'>
      <h1>Pokedex</h1>
      <div>
        {result.results.map((pokemon) => (
          <Pokemon key={pokemon.name} pokemon={pokemon} />
        ))}
      </div>
    </main>
  )
}

export default App

Теперь нам нужно только передать url в useSWR, вместо передачи url и метода fetcher. Давайте также немного подправим компонент Pokemon.

import React from 'react'
import useSWR from 'swr'

export const Pokemon = ({ pokemon }) => {
  const { name } = pokemon
  const url = 'https://pokeapi.co/api/v2/pokemon/' + name

  const { data, error } = useSWR(url)

  if (error) return <h1>Something went wrong!</h1>
  if (!data) return <h1>Loading...</h1>

  return (
    <div className='Card'>
      <span className='Card--id'>#{data.id}</span>
        <img
          className='Card--image'
          src={data.sprites.front_default}
          alt={name}
        />
        <h1 className='Card--name'>{name}</h1>
        <span className='Card--details'>
          {data.types.map((poke) => poke.type.name).join(', ')}
        </span>
    </div>
  )
}

Вы уже видите, что у нас больше нет функции fetcher, благодаря глобальной конфигурации, которая передает функцию useSWR под капотом.

Теперь вы можете использовать глобальную функцию fetcher везде в своем приложении. Единственное, что нужно хуку useSWR для получения удаленных данных, - это URL.

Однако мы можем еще больше усовершенствовать настройку, создав пользовательский хук, чтобы не объявлять URL снова и снова, а просто передать в качестве параметра путь.

Расширенная настройка путем создания пользовательского хука

Для этого необходимо создать новый файл в корне проекта с именем useRequest.js (вы можете назвать его как угодно) и добавить в него следующий блок кода.

import useSwr from 'swr'

const baseUrl = 'https://pokeapi.co/api/v2'

export const useRequest = (path, name) => {
  if (!path) {
    throw new Error('Path is required')
  }

  const url = name ? baseUrl + path + '/' + name : baseUrl + path
  const { data, error } = useSwr(url)

  return { data, error }
}

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

Затем этот URL передается в качестве параметра хуку useSWR, чтобы иметь возможность получить удаленные данные и вернуть их. Если же путь не передан, выдается ошибка.

Отлично! Теперь нам нужно немного подправить компоненты, чтобы использовать наш пользовательский хук.

import React from 'react'
import { useRequest } from './useRequest'
import './styles.css'
import { Pokemon } from './components/Pokemon'

function App() {
  const { data: result, error } = useRequest('/pokemon')

  if (error) return <h1>Something went wrong!</h1>
  if (!result) return <h1>Loading...</h1>

  return (
    <main className='App'>
      <h1>Pokedex</h1>
      <div>
        {result.results.map((pokemon) => (
          <Pokemon key={pokemon.name} pokemon={pokemon} />
        ))}
      </div>
    </main>
  )
}

export default App

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

Давайте также обновим компонент Pokemon.

import React from 'react'
import { useRequest } from '../useRequest'

export const Pokemon = ({ pokemon }) => {
  const { name } = pokemon
  const { data, error } = useRequest('/pokemon', name)

  if (error) return <h1>Something went wrong!</h1>
  if (!data) return <h1>Loading...</h1>

  return (
    <div className='Card'>
      <span className='Card--id'>#{data.id}</span>
      <img
        className='Card--image'
        src={data.sprites.front_default}
        alt={name}
      />
      <h1 className='Card--name'>{name}</h1>
      <span className='Card--details'>
        {data.types.map((poke) => poke.type.name).join(', ')}
      </span>
    </div>
  )
}

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

Надеюсь, вам понравится эта классная библиотека. Однако нам еще есть что открыть для себя, ведь SWR предлагает так много возможностей, и одна из них - useSWRPages, которая представляет собой хук для удобной постраничной обработки данных. Итак, давайте используем этот крючок в проекте.

Размещение наших данных по страницам с использованием SWRPages

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

Теперь создадим новый файл в корне проекта usePagination.js и используем его в качестве пользовательского хука для постраничной публикации.

import React from 'react'
import useSWR, { useSWRPages } from 'swr'
import { Pokemon } from './components/Pokemon'

export const usePagination = (path) => {
  const { pages, isLoadingMore, loadMore, isReachingEnd } = useSWRPages(
    'pokemon-page',
    ({ offset, withSWR }) => {
      const url = offset || `https://pokeapi.co/api/v2${path}`
      const { data: result, error } = withSWR(useSWR(url))

      if (error) return <h1>Something went wrong!</h1>
      if (!result) return <h1>Loading...</h1>

      return result.results.map((pokemon) => (
        <Pokemon key={pokemon.name} pokemon={pokemon} />
      ))
    },
    (SWR) => SWR.data.next,
    []
  )

  return { pages, isLoadingMore, loadMore, isReachingEnd }
}

Как вы видите, здесь мы начинаем с импорта useSWRPages, который является помощником, позволяющим легко размещать данные на страницах. Он получает 4 аргумента: ключ запроса pokemon-page, который также используется для кэширования, функцию для получения данных, которая возвращает компонент, если данные успешно получены, и еще одну функцию, которая принимает объект SWR и запрашивает данные со следующей страницы, а также массив зависимостей.

После получения данных функция useSWRPages возвращает несколько значений, но здесь нам нужны 4 из них: страницы, которые являются компонентом, возвращаемым вместе с данными, функция isLoadingMore, которая проверяет, получены ли данные в настоящее время, функция loadMore, которая помогает получить больше данных, и метод isReachingEnd, который определяет, есть ли еще данные для получения или нет.

Теперь у нас есть пользовательский хук, который возвращает необходимые значения для постраничной обработки данных, и мы можем перейти к файлу App.js и немного подправить его.

import React from 'react'
import { usePagination } from './usePagination'
import './styles.css'

export default function App() {
  const { pages, isLoadingMore, loadMore, isReachingEnd } = usePagination(
    '/pokemon'
  )

  return (
    <main className='App'>
      <h1>Pokedex</h1>
      <div>{pages}</div>
      <button
        onClick={loadMore}
        disabled={isLoadingMore || isReachingEnd}
      >
        Load more...
      </button>
    </main>
  )
}

После импорта хука usePagination мы можем передавать путь в качестве параметра и получать возвращаемые значения. А поскольку pages - это компонент, нам не нужно циклически просматривать данные или что-то в этом роде.

Далее мы используем функцию loadMore на кнопке, чтобы получить больше данных и отключить ее, если операция получения не завершена или если нет данных для получения.

Отлично! С этими изменениями мы можем теперь перейти в корень проекта и запустить сервер с помощью этой команды для предварительного просмотра нашего приложения.

yarn start

Или если вы используете npm:

npm start

Вы должны увидеть, что данные успешно получены, и если вы нажмете на кнопку, SWR будет получать новые данные.

До сих пор мы видели на практике библиотеку SWR, и я надеюсь, что вы находите в ней пользу. Однако у нее еще есть некоторые возможности. Давайте погрузимся в эти функции в следующем разделе.

Другие возможности SWR

В библиотеке SWR есть множество удобных вещей, которые упрощают создание приложений на React.

Focus Revalidation

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

Refetch on Interval

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

Локальная мутация

С помощью SWR вы можете установить временное локальное состояние, которое будет автоматически обновляться при получении новых данных (ревалидации). Эта функция особенно актуальна, когда вы имеете дело с подходом Offline-first, она помогает легко обновлять данные.

Восстановление позиции прокрутки

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

Зависимая выборка

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

Таким образом, SWR помогает повысить удобство работы пользователя в любом вопросе. У него больше возможностей, и во многих случаях его лучше использовать вместо Fetch API или библиотеки Axios.

Заключение

В этой статье мы увидели, почему SWR - это потрясающая библиотека. Она позволяет удаленно получать данные с помощью React Hooks и помогает упростить некоторые расширенные функции, такие как пагинация, кэширование данных, повторная выборка по интервалу, восстановление позиции прокрутки и так далее. SWR также не зависит от бэкенда, что означает, что он может получать данные из любых API или баз данных. В целом, SWR значительно повышает удобство работы с React-приложениями, у него большое будущее, и вы должны следить за ним или лучше использовать его в своем следующем React-приложении.

Вы можете посмотреть готовый проект в прямом эфире здесь.

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


Teacher Army - это команда опытных наставников, готовых помочь вам с особенностями работы с SWR. Если вам нужна помощь во фронтенд-разработке, просто перейдите по ссылке и оставьте заявку.
Мы с удовольствием подберем для вас подходящего ментора по программированию, который проведет с вами индивидуальную консультацию и объяснит любую тему, связанную с SWR или фронтенд-разработкой.

Оригинальная статья

Перевела Дарья Крещёнова

27.11.2023

Читать полностью

Как работает React Suspense

React Suspense - это компонент React, который приостанавливает отрисовку компонентов до выполнения определенного условия и отображает запасной вариант - fallback. Этот запасной вариант является обязательным, и это может быть строка или другой компонент, например, спиннер. Так же React Suspense работает только с динамическим импортом, он же ленивая загрузка.

// Dynamic import
const CatAvatar = React.lazy(() => import('./path/to/cat/avatar'));

// Displays "loading..." to the user until CatAvatar has finished loading.
const AppContainer = () => (
  <React.Suspense fallback="loading...">
    <CatAvatar />
  </React.Suspense>
);

Почему React Suspense полезен?

Самая большая проблема с JavaScript-приложениями в наши дни - это большая нагрузка, которую приходится платить пользователям за загрузку и выполнение кода. Это очень дорого для пользователей со слабыми устройствами и сетевыми соединениями. Вот почему разделение кода JavaScript-приложения является чрезвычайно полезным. React.lazy позволяет очень просто сообщить Webpack и нашему приложению, что определенные файлы и код могут быть загружены позже в приложении. Это поможет уменьшить первоначальный размер кода, передаваемого пользователю.

Но вместе с этим возникает другая проблема. Пока пользователь перемещается по приложению JavaScript, а код загружается во время выполнения, пользователю приходится ждать, пока сеть не закончит загрузку и выполнение следующего фрагмента кода. Именно здесь на помощь приходит React.Suspense, который отображает пользователю состояние загрузки и делает это весьма изящно. React.Suspense дает пользователям знать, что идет загрузка следующего фрагмента, и скоро он будет у вас!

React может работать с несколькими React-компонентами

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

const CatAvatar = React.lazy(() => import('./path/to/cat/avatar'));
const ThorAvatar = React.lazy(() => import('./path/to/cat/thor-avatar'));

const AppContainer = () => (
  <React.Suspense fallback="loading...">
    <CatAvatar />
    <ThorAvatar />
  </React.Suspense>
);

Так же вы можете иметь несколько вложенных компонентов React.lazy внутри React.Suspense.

Обработка ошибок в React.Suspense и React.lazy

С React.lazy и React.Suspense может возникнуть несколько проблем. Интернет-соединение оборвалось в процессе загрузки. Недостаточная мощность устройства. Неправильное имя пути к файлу компонента React. Как же мы справляемся со сбоями загрузки?

У React есть стандартный шаблон для изящной обработки ошибок. Они раскрыли 2 жизненных цикла React, статический getDerivedStateFromError() и componentDidCatch(). Эти два жизненных цикла похожи тем, что оба срабатывают при возникновении ошибки в дочернем компоненте. Разница заключается в следующем - static getDerivedStateFromError() требует, чтобы вы вернули объект для обновления состояния. Что касается componentDidCatch(), то это метод, который ничего не возвращает и вам придется вызвать useState() или setState() для обновления состояния компонента.

Я собираюсь добавить к приведенному выше примеру React.Suspense.

const CatAvatar = React.lazy(() => import('./path/to/cat/avatar'));

class ErrorHandler extends React.Component {
  state = {
    hasError: false,
  };

  static getDerivedStateFromError(err) {
    return { hasError: true };
  }

  render() {
    if (this.state.hasError) {
      return (
        <p>
          Loading has failed. Try refreshing the browser!
        </p>
      );
    }

    return this.props.children;
  }
}

const AppContainer = () => (
  <ErrorHandler>
    <React.Suspense fallback="loading...">
      <CatAvatar />
    </React.Suspense>
  </ErrorHandler>
);

Если при загрузке CatAvatar произошла ошибка, будет выведено сообщение об ошибке.

React Suspense для получения данных

Как было показано выше, React.Suspense работает только с динамическим импортом. Он предназначен только для поддержки ленивой загрузки. Но в настоящее время команда React упорно работает над тем, чтобы React.Suspense работал и с выборкой данных. React.Suspense связан с новым режимом, над которым работает React, под названием Concurrent Mode.

Режим Concurrent предоставляет новый набор функций, который решает первоначальную проблему, описанную ранее в этой статье. Эта проблема заключается в слабых устройствах и плохих сетевых соединениях. Как инженеры мы хотим быть уверены, что предоставляем одинаково быстрые и надежные приложения всем пользователям. Включенный Concurrent Mode открывает новый набор возможностей для React.Suspense.

Во-первых, чтобы включить Concurrent Mode, необходимо установить экспериментальную версию React.

npm install --save react@0.0.0-experimental-5faf377df react-dom@0.0.0-experimental-5faf377df

Второй шаг заключается в замене того, как мы прикрепляем приложение React к оболочке HTML.

// Current
ReactDOM.render(<App />, document.getElementById('root'));

// Concurrent Mode
ReactDOM
  .createRoot(document.getElementById('root'))
  .render(<App />);

Вот и все! Все, что вам нужно сделать, это установить экспериментальный режим React и изменить 1 строчку кода. После этого React.Suspense будет по умолчанию не только ждать динамического импорта, но и получать данные.

React.SuspenseList - API

Еще одна новая функция, которая была добавлена в Concurrent Mode - React SuspenseList. Это компонент React, который принимает несколько компонентов React.Suspense и позволяет вам организовать их раскрытие.

// Cat 1 fetch time: 45ms
// Cat 2 fetch time: 100ms
// Cat 3 fetch time: 10ms

// Отображает всех дочерних элементов, когда выборка всех данных завершена.
<React.SuspenseList revealOrder="together">
  <React.Suspense fallback={'Loading first cat...'}>
    <Cat id={1} />
  </React.Suspense>
  <React.Suspense fallback={'Loading second cat...'}>
    <Cat id={2} />
  </React.Suspense>
  <React.Suspense fallback={'Loading third cat...'}>
    <Cat id={3} />
  </React.Suspense>
</React.SuspenseList>

// Всегда начинается сверху вниз: Cat 1, Cat 2, Cat 3
<React.SuspenseList revealOrder="forward">
  <React.Suspense fallback={'Loading first cat...'}>
    <Cat id={1} />
  </React.Suspense>
  <React.Suspense fallback={'Loading second cat...'}>
    <Cat id={2} />
  </React.Suspense>
  <React.Suspense fallback={'Loading third cat...'}>
    <Cat id={3} />
  </React.Suspense>
</React.SuspenseList>

// Всегда начинается снизу вверх: Cat 3, Cat 2, Cat 1
<React.SuspenseList revealOrder="backwards">
  <React.Suspense fallback={'Loading first cat...'}>
    <Cat id={1} />
  </React.Suspense>
  <React.Suspense fallback={'Loading second cat...'}>
    <Cat id={2} />
  </React.Suspense>
  <React.Suspense fallback={'Loading third cat...'}>
    <Cat id={3} />
  </React.Suspense>
</React.SuspenseList>

React.SuspenseList работает только с ближайшими компонентами React.Suspense. Не более чем на один уровень вглубь.

Заключение

На данный момент React.Suspense работает только с динамическим импортом, он же ленивая загрузка. Если вы не уверены, когда его использовать, следуйте этому руководству:

  1. Начните с уровня маршрутизатора. Посмотрите это руководство, в котором показано, как реализовать React.Suspense и React.lazy() для добавления ленивой загрузки в React router.
  2. Разделяйте только те фрагменты приложений React, которые не являются сверхкритичными для пользователя.

В ближайшем будущем React, React.Suspense будет использоваться не только для ленивой загрузки, но и для выборки данных.


Так же с особенностями работы React Suspense могут помочь наставники Teacher Army.
Переходите по ссылке и оставляйте заявку, а мы подберем вам подходящего ментора по программированию, который на индивидуальном созвоне объяснит любую тему.

Оригинальная статья

Перевела Дарья Крещенова

20.03.2023

Читать полностью

Как эффективно учиться программированию по YouTube роликам

Многие начинают обучение программированию на YouTube. Смотрят ролики, подписываются на канал. Это невероятно мотивирует, многие вещи кажутся простыми и понятными. До того момента, пока не начнёшь повторять за автором. Да, чтобы начать повторять, нужно сделать усилие над собой. Мозг очень сопротивляется. Он говорит тебе: "Да мне и так всё понятно, зачем тут что-то повторять".

Но реальность такова, что это ловушка. Мозг любит, когда легко и весело, он экономит свои ресурсы и защищает их, поэтому так себя ведёт. Но нужно понять, что без повторения не будет изучения.

Давайте я покажу алгоритм, по которому можно начать качественно изучать программирование на YouTube.

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

Шаг первый. Завести аккаунт на GitHub, если его у вас ещё нет. Там бы будем публиковать код. Сможем им делиться с другими, а так же публиковать приложение в интернете. Публикацию мы оставим за пределами этой статьи, но знайте, что такая возможность есть.

Шаг второй. Выбрать канал или каналы, на котором будете обучаться. Мы за основу возьмём канал Мэлсика. Даня отличный парень и доходчиво объясняет сложные вещи. В своих видео он показывает решение интересных прикладных задач и не топит вас в скучной теории. Рекомендую его канал, если вы хотите изучать python или c++. Проходите по ссылке и подписывайтесь.

Шаг третий. Выбрать для себя маршрут. Оглянуться на видео с канала и выбрать несколько из них, 3-5, которые связаны общей идеей, языком и инструментами. Общность важна, чтобы мозгу было проще делать переход от одного видео к другому. От одного материала к другому. Расставляем их от простого к сложному по субъективной оценке. Большая точность нам не нужна. Мы выбрали следующие видео:

Шаг четвертый. Практика!

Как воспроизводить музыку при помощи Python | PYGLET

Сначала сделаем веселую и простую задачу - воспроизведем музыку. Могли бы вы подумать, что mp3-плеер будет так просто запрограммировать? Несколько строк кода и у нас рабочая программа, которая радует нас любимой музыкой.

Как создать будильник на Python | DATETIME

Почувствовав силу, двигаемся дальше. Добавим логики нашему плееру, и вот у нас готов будильник. Теперь программа не только радует, но еще и оказывается очень полезной. Будет нежно нас будить любимой музыкой. Или не нежно. Тут уж как запрограммируем.

Будильники это уже не несколько строк кода. Чувствуете мощь? Чувствуете, что можете свернуть горы? Я да. Нужно перепечатать код, разобраться, что значит каждая строчка и принять, что вы написали этот код. Еще не придумали, но написали. Для придумывания время еще придет. Все впереди.

Создаем парсер на Python | парсинг данных | BeautifulSoup4

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

Создание Telegram бота на Python | AIOGRAM

С парсером разобрались. Теперь запрограммируем бота в Telegram. Бот - это программа, с которой можно общаться в чате, перекладывать какую-то рутину и так далее. Изучите код, разберитесь, как его нужно запускать, получив токен, и вот у вас свой карманный бот. Поздравляю!

Telegram бот и парсер Wikipedia | AIOGRAM | PYTHON

Мы изучили и отработали программирование отдельных задач. А теперь давайте объединим полученные знания и создадим бота, который будет парсить сайт! А именно Wikipedia. Бот будет обрабатывать наш запрос, загружать страницу википедии и показывать нам ее. Практически своя карманная энциклопедия без захода в браузер. И тут все делаем так же, как на предыдущих шагах: смотрим код на видео, перепечатываем, разбираем каждую строчку.

Итог

Подведем итог. На youtube-роликах можно учиться программировать, но самое главное не заниматься самообманом, а ответственно подходить к работе с кодом. Нужно разбирать код на видео, перепечатывать его и где-то даже писать самостоятельно.

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

Желаю вам удачи в освоении программирования и достижении новых высот. Пишите код, становитесь круче!


Олег Акинин

05.12.2022

Читать полностью

Пропасть между джунами и сеньорами

Вы замечали целую пропасть, разрыв между джунами и синьорами? Разрыв во времени. Разрыв в знаниях. Разрыв в профессиональном опыте. Разрыв в житейском опыте. Да что там, они даже разговаривают на разных языках.

В начале моей карьеры программистом, когда я только устроился в Interfaced, мы с ребятами ходили вместе обедать. Мне было трудно поддержать диалог с ними. Я сидел, слушал их, но ничего не понимал. Ни-че-го. Они вроде использовали слова, которые я знаю. Предложения из них собирали правильные. Но какая информация в них содержится я не мог понять.

В эти моменты в моей голове была только одна мысль и страх: "Надеюсь меня не спросят ни о чём, а то не смогу ответить и все поймут, что я тупой. И выгонят из программистов навсегда". Вот так я продолжал сидеть, слушать и молчать. Подобные страхи, когда только начинаешь работать после обучения, тормозят профессиональный рост. Обратиться за помощью к коллегам страшно и неудобно. Приходиться искать ответы самому, что порой малоэффективно.

Но что будет, если попросить помощи? Ты становишься умнее и узнаешь больше. В один момент разрыв между джуном и синьором сокращается. При этом посчитает ли кто-нибудь джуна тупым если он уточнит какие-то детали, которые не понимает? Вряд ли.

Мы в Teacher Army понимаем как тяжело джунам в начале пути и поэтому готовы ответить на любые вопросы. Помни, что самый глупый вопрос - это незаданный вопрос. Мы хотим чтобы вы получили ответы, тем самым приближаясь к уровню синьора. С каждым вопросом и последующим ответом пропасть между джуном и синьором сокращается.

На консультациях с наставником ты можешь получить ответы на свои вопросы. Не нужно ломать голову как написать понятно. Созвонись с наставником и просто спроси. Говорить легче, чем писать. Говорить быстрее, чем писать. И ответ получаешь в тот же момент. Для сохранения информации у нас есть возможность записи встречи.

Наши наставники открыты к общению. Они хотят делиться своим опытом и помогать тебе. Приходи к нам в Teacher Army. Стань ближе к профессионалам


Олег Акинин

10.10.2022

Читать полностью

Подборка литературы для backend разработчика

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

Архитектура

  1. Рефакторинг гуру(сайт с енотиком). Там и про паттерны и про рефакторинг. Все хорошее статьи книги и возможно видеокурс(я его не смотрел). Как раз для тех кто начинает улучшать качество своего кода Остальные книги для тех кто уж "понюхал пороха":
  2. Роберт Мартин: Чистая архитектура. Искусство разработки программного обеспечения.
  3. М. Фаулер "Рефакторинг. Улучшение существующего кода"
  4. Роберт Мартин Чистый код: создание, анализ и рефакторинг - мне предудщая книга ближе, но как там довольно много интересный вещей, использую как справочник "хороших практик", но при этом эта книга хороша и для полного прочтения
  5. Не рекомендую для начала(только после такого прокачайтесь) читать банду 4-х. Книга крутая, но для новичков может быть сложной.
  6. Майкл Нейгард Release it! Проектирование и дизайн ПО для тех, кому не всё равно. - просто интересная книжка. Не рекомендую читать для обучения.
  7. Руководство по паттернам микросервисам, очень крутое https://docs.microsoft.com/ru-ru/azure/architecture/reference-architectures/saga/saga

БД

  1. mysql документация
  2. Вадим Ткаченко, Бэрон Шварц, Петр Зайцев - MySQL по максимуму
  3. Ян Робинсон, Джим Вебер, Эмиль Эифрем "Графовые базы данных. Новые возможности для работы со связанными данными" - если интересуют графовые базы данных.
  4. Postgresql - хорошая документация переведенная на русский язык.
  5. Все книги postgrespro - https://postgrespro.ru/education/books

Языки

Общее для некоторых языков(php, python, nodejs) Для людей, которым сложно дается документация на первое время рекомендую книжки Вадима Панова. Он довольно неплохо все разжевывает, чтобы начать программировать, но там только базовые вещи, которые нужно позднее добавлять выдержками из документации и других источников

PHP

Литературу под php надо подбирать очень строго, потому что некоторые учебники учат программировать в стиле "старого php", что нам не подходит. Может подойти для начальных этапов, чтобы в принципе позапускать программы, но к реальным приложениям это имеет малое отношение, хоть такие приложения и встречаются (даже в простых фриланс проектах, популярным становится laravel).

  1. PHP и MySQL. Разработка веб-приложений, Денис Колисниченко. - ЭТУ КНИГУ РЕКОМЕНДУЮ ТОЛЬКО В ТОМ СЛУЧАЕ ЕСЛИ ЧУВСТВУЙТЕ ЧТО НЕ ИДЕТ НИЧЕГО ДРУГОЕ. В этой книге не будет ничего про то, что нужно бекенд разработчику. Но сама книжка относительно простая. Ее прочтение может, помочь вам начать и уже читать что-то более интересное.
  2. https://github.com/getjump/ru-php-the-right-way, https://phptherightway.com/, http://phptherightway.ru/ - еще раз порекомендую это
  3. Мэтт Зандстра: PHP 8. Объекты, шаблоны и методики программирования - по отзыву моего друга в качестве совсем первой книги это тяжело. Рекомендую ее после того как вы уже поняли что такое классы.
  4. Domain-Driven Design in PHP by Carlos Buenosvinos (Author), Christian Soronellas (Author), Keyvan Akbary (Author) - для профи
  5. Михаил Фленов "PHP глазами хакера" - любопытная книга, но не для обучения разработке.
  6. https://thephpleague.com/ - полезный ресурс. В основном там библиотеки, но все равно круто.
  7. https://t.me/beerphp - крутой чувак, очень доступно все рассказывает.
Фреймворки

Немного пройдемся по фреймворкам. Как правило, документация лучшая книга. Ее довольно понятно пишут к популярным фреймворкам. Но где-то возможно объяснено получше/понагляднее/проще. Я рассмотрю только symfony/laravel.

Symfony
  1. На официальном сайте очень много книг, в том числе перевод документации https://symfony.com/doc/current/the-fast-track/ru/index.html.
  2. Matthians Noback - один год симфони, немного старовата, но возможно там объяснят некоторые тонкости, которые непонятны. Потому как справочник может сгодиться.
Laravel
  1. Документация laravel неплохо написана и есть переводы на русский. Аналогично книга по symfony
  2. Владимир Дронов laravel 8 быстрая разработка веб-сайтов на php - Это рекомендация от Максима, который был в моем посте про ментороства. Он сказал, что когда начинал, ему было понятно. То есть для начинающих.
  3. Стаффер М: Laravel. Полное руководство. 2-е издание - если вы понимайте документацию laravel и понимайте что там написана, то не думаю что эта книга стоит того, чтобы ее специально покупать. Но если возникают трудности, возможно эта книга вам поможет их преодолеть.
  4. https://laravel-beyond-crud.com/ - к сожалению человек не продает книгу отдельно. Если вам удастся ее раздобыть, или найти посты на основе нее, то книга стоящая дла начинающих.
  5. https://github.com/alexeymezenin/laravel-best-practices

Python

То что я сейчас скажу про python это не про ml, а про web/desktop/простые скрипты. Я очень долго искал хорошие книги по python. Меня очень сильно раздражает, когда в python рекламируют, как "простой язык для обучения". Напоминает старую историю про то, что залесть на слона бесплатно, а вот слезть... Python действительно в некоторых аспектах на начале проще чем, например, с++/java, а некоторым даже кажется проще чем php. Но руководств к тому как писать чистый код на python я не нашел. При этом язык живет своей жизнью и реализует популярные концепции(например ООП) очень по-своему. Насколько я вижу в интернете, многих питонситов это устраивает. Я ничего не имею против, но я начал писать эту статью, потому что занимаюсь менторством и ко мне часто приходят начинающие и говорят фразу, что "я начал изучать python, потому что это самый популярный и простой язык", хотя на деле они просто не смогли определиться и понять что им надо. Для меня это звучит как "я хотел научиться плавать, и услышал, что лодка мне в этом поможет".

Мое мнение, что питон далеко не для всех, если вы собрались учить его для участия в больших проектах(для мелких проектов/мат вычислений, то что я написал практически не имеет значения).

Если вы все же решились изучать python для веб вакансии. То вот небольшой план(все конечно должно очень сильно миксоваться с практикой)

Начало
  1. Любая книга вроде этой - https://www.litres.ru/allen-b-dauni/osnovy-python-nauchites-dumat-kak-programmist-64838906/ Главное, чтобы +/- доступно(для вас) излагались основные понятия(циклы, основные типы данных, итераторы, генераторы, ООП, многопоточка). Можете загуглить содержания этой книги, чтобы лучше понять о чем я говорю. Но если вы осилите оф. документацию, до это будет даже лучше.
  2. https://digitology.tech/docs/python_3/tutorial/index.html - вот собственно переделенная документация(https://www.python.org/ - если на английском вам достаточно).
Продолжение
  1. Автостопом по python - на мой взгляд очень крутая книга, которая после знания основ даст понимание что делать дальше(главу для профи порекомендую ниже)
  2. Чистый python - https://www.litres.ru/beyder-d/chistyy-python-tonkosti-programmirovaniya-dlya-profi-39123332/ Неплохая книга, но возможно будет скучной.
Профи

То из-за чего я начал этот пост, долгое время не мог понять куда копать. Привыкший к IOC-контенерам, я не понимал как питонисты организуют свой код в больших проектах. Читал вот это https://habr.com/ru/post/461511/ и не понимал что происходит. Натыкался на разные подходы в том числе наткнулся на вот это видео - https://www.youtube.com/watch?v=imW-trt0i9I , которое прояснило для меня некоторые моменты. По итогу наткунлся на вот эту книгу

  1. https://www.litres.ru/deyn-hillard/sekrety-python-pro-pdf-epub-64083647/ - на мой взгляд хорошая книга.
Остальное

Если питонисты откомментируют этот раздел я буду признателен. И также скину несколько ресурсов по python:

  1. https://www.youtube.com/watch?v=8hscvGY7EhI - прикольный чувак, который хорошо шарит в python и все разжевывает
  2. https://digitology.tech/ - хороший русскоязычный ресурс по джанго

Golang

По аналогии с python очень долго не мог найти хорошие ресурсы

  1. Программирование на Go. Разработка приложений XXI века | Саммерфильд Марк
  2. https://www.litres.ru/mihalis-cukalos-27713196/golang-dlya-profi-64073297/ - Golang для профи
  3. https://dev.to/ankit01oss/7-github-projects-to-make-you-a-better-go-developer-2nmh - просмотрите все репозитории, там и фремворки и структура проектов и кучу всего еще
  4. Михалис Цукало Golang для профи. - Для тех кто столкнется/захочет перейти в go. Эта книга мне очень понравилась, при переходе на язык go. Есть неплохая Марк Саммерфильд Программирование на Go. Разработка приложений XXI века - Если в дальнешем заинтересует/столкнетесь в работе с golang. Но это больше.

Остальное

Здесь просто порекомендую книги, которые мне очень понравились. Но также говорю, что сейчас документацию к популярным технологиям пишут неплохую и как правило оформляют в виде книг.

  1. Если будете ударяться в javascript. Серия книг "Вы не знайте JS", очень хорошая.
  2. Шукла Пранав, Кумар Шарат Elasticsearch, Kibana, Logstash и поисковые системы нового поколения - хороший пересказ документации к elastic :)
  3. Адитья Бхаргава. Грокаем алгоритмы. Иллюстрированное пособие для программистов и любопытствующих - в своем плане, я ни слова не сказал об алгоритмах. При этом на деле некоторые базы computer science и алгоритмы желательны. Это не всегда понадобится вам в работе в явном виде и php-шников редко спрашивают алгоритмы, тем не менее это полезно.
  4. И в заключение. Не стоит пугаться такого огромного списка литератры. Далеко не все вам понадобится для первого рабочего места(причем даже и для второго и для третьего). Некоторые вещи я еще не дочитал, некоторые вам могут не понадобится. Некоторые из этих книг, я прочел недавно.

Прочитать в блоге Андрея


Андрей Никулин

27.09.2022

Читать полностью

Квартирник Teacher Army по индексу 2

Привет, ребята и девчата! Мы по вам соскучились!

Вот и лето прошло, словно и не бывало, ну а мы не унываем и продолжаем собираться, чтобы отлично провести время в жарких дискусскиях. Предыдущий выпуск показал, что интерес к тематике и проблематике есть. Мы поговорили про то какие фреймворки мы используем и почему, и что же тут может пойти не так!

Тема нового выпуска "Инженерная культура — зачем? Как? Почему?". Будем говорить про то, что такое инженерная культура, зачем она нужна и кому. Почему преждевременные оптимизации не помогают, а часто лишь ухудшают ситуацию с производительностью? Почему люди плохо разбираются в библиотеках и фреймворках в которых они работают? Что с этим можно делать и как жить?

Нам очень важно ваше мнение и ваши истории. Приходите на Квартирник Teacher Army, примите участие в дискуссии или просто послушайте других. Мы ждём вас, друзья!

Мы будем вас ждать 29.09.2022 в четверг в 19:00 по Москве в нашем уютном Google Meet! Подключайтесь хоть с компьютера, хоть с телефона в парке😉

Заполните google форму и мы пришлем вам приглашение.


Евгений Щепотьев

16.09.2022

Читать полностью

Итоги Квартирника Teacher Army по индексу 1

На прошлой неделе прошёл Квартирник по индексу 1, и он нас несказанно порадовал и впечатлил. Если в прошлый раз на нём было пять участников и все так или иначе были знакомы, то вчера было уже пятнадцать человек. Многие видели друг друга впервые, но это не помешало поделиться своим мнением с остальными.

Суховато, да? Ну в общем, ребята, мы затерли про технологии, навтыкали реакту и попытались понять, зачем мы тащим оверхедные технологии в проект.

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

С другой стороны, мы оказываемся заложниками собственных знаний и берём то, что знаем и понимаем. Пусть оно не идеально подходит, зато мы знаем, где надо смазать, чтобы поехало.

С наставниками Teacher Army поговорили про то, как важно расширять свои границы и не застревать в чём-то одном. Развиваться как человек и специалист в широком поле, чтобы иметь возможность для манёвра. Быть не только React-кодером, а стать разработчиком и инженером.

Ребята, вы крутые, спасибо, что пришли! И Квартирник крутой! Ждем вас снова! Участвуйте в дискуссиях и задавайте вопросы.

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


Олег Акинин

08.09.2022

Читать полностью

Квартирник Teacher Army по индексу 1

Привет, ребята и девчата! Мы по вам соскучились!

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

Тема нового выпуска "Зачем швейцарский нож на кухне?". Будем говорить про то, когда нужен React, а когда нет. Когда нужно гнаться за чем-то модным, а когда подойдут консервативные решения? Как научиться делать объективный выбор для пользы бизнесу и не поддаваться своим желаниям и привычкам? Как затаскивать новые для себя технологии без ущерба для проекта?

Нам очень важно ваше мнение и ваши истории. Приходите на Квартирник Teacher Army, примите участие в дискуссии или просто послушайте других. Мы ждём вас, друзья!

Мы будем вас ждать 01.09.2022 в четверг в 19:00 по Москве в нашем уютном Google Meet! Подключайтесь хоть с компьютера, хоть с телефона в парке😉

Заполните google форму и мы пришлем вам приглашение.


Олег Акинин

24.08.2022

Читать полностью

Квартирник Teacher Army

Привет, ребята и девчата! На связи Teacher Army!

Мы так соскучились по живому общению и решили устроить Квартирник Teacher Army. Это онлайн-митап в Google Meet, где можно послушать и обсудить заданную тему. Включайте камеру, берите микрофон, расскажите, что думаете. Нам интересно ваше мнение!

Давайте отойдем от привычного нам прослушивания подкастов. На нашем Квартирнике вы сможете поучаствовать в дискуссии, поделиться опытом и высказать свое мнение по теме.

Тема нулевого выпуска: "Влияние характера программиста на стиль и процесс разработки". Встречу проведут Олег Акинин и Женя Щепотьев.

Вы задумывались, почему кто-то из коллег пишет много кода, создавая фичу за фичей, а кто-то неторопливо рефакторит существующий код и не спешит писать новый? Почему так происходит? Кто из них хороший программист, а кто плохой (спойлер-все хорошие)? Какой подход ближе к тебе?

Наливайте кофе, заваривайте чай, открывайте вино, берите пивко и го к нам на квартирник. Поговорим по душам о разработке и разработчиках.

Подключайтесь, мы будем вас ждать 22.07.2022 в 19:00 по Москве!

Заполните google форму и мы пришлем вам приглашение.


Олег Акинин

18.07.2022

Читать полностью

Новая услуга - code-review

Привет, ребята и девчата! Teacher Army заряжает энергией, позитивом и движением вперед! Мы запустили новую возможность получить фидбек от профессиональных разработчиков - code-review.

Ты можешь отдать на ревью любой проект и получить:

  • комментарии в формате пулл-реквеста на github к своему коду и решениям;
  • дополнительные варианты решения имеющейся задачи;
  • предложения по архитектурным решениям для снижения сложности разработки в дальнейшем.

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

Teacher Army хочет это изменить. Наша цель - повысить культуру шаринга знаний и опыта в среде разработчиков. Получи фидбек, повысь качество своих решений уже сейчас!


Олег Акинин

03.06.2022

Читать полностью

Быть или не быть программистом

Любой может стать программистом? Да. Любой может стать программистом? Нет. Именно такие противоречивые ответы можно найти в интернете на такой простой вопрос. Но почему? Почему всё так противоречиво?

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

Кто-то скажет, нужно знать алгоритмы и структуры данных. Но алгоритмы и структуры данных это и есть программирование. Их приходится изучать на протяжении всей своей карьеры.

Кто-то скажет, нужно знать логику. Это конечно правда. Все операции в программировании основаны на логике и программируем мы бизнес-логику. Но разве есть человек, который не понимает логику? Я сомневаюсь. Как же тогда он общается с другими людьми? Если можешь отличить право от лева, то if от else так же отличишь.

Что есть ещё в топе необходимых вещей? Английский. Есть мнение, что если не можешь бегло читать по-английски, то начинать программировать рано. Ну совсем нет. Да, английский правда нужен. Подавляющее большинство информации, документации, статей на английском языке. Но на русском она тоже есть. А если чего-то нет, то онлайн-переводчики нас спасут. Начинать можно и с этого. Но мы используем английские слова для названий переменных и функций. Весь код пишется на английском. Но в момент обучения весь код ты пишешь сам и постепенно пополняешь словарный запас.

Получается, что без всего этого можно стать программистом. А без чего по-настоящему нельзя? Почему у кого-то не получается? Фрустрация. Без её преодоления действительно нельзя стать программистом.

Весь процесс написания кода, продумывания решения задачи протекает через преодоление преград. Нас как будто выкинули в океан и сказали: "Плыви в нужном направлении. Иначе крышка". Что? В нужном? А точнее можно? Нет, нельзя. Ок. И мы плывем. Кто-то брасом фигачит. Кто-то строит плот из плавающего мусора. Кто-то обращается за помощью к ребятам с проплывающего корабля. А кто-то не может совладать с паникой и моральной тяжестью всего этого и сдается.

Так вот, чтобы стать программистом, нужно всего-навсего не сдаваться. Да, это не просто. Да, иногда не понятно в каком направлении двигаться. Но потом будет легче и понятнее. Сложности будут всегда, но это будут уже другие сложности. И после каждой задачи, в конце, ждёт награда. Признак того, что ты можешь. Что ты справляешься. Что ты идёшь к своей цели. Продолжай в том же духе!


Олег Акинин

27.03.2022

Читать полностью

Новая услуга - Собеседование

Мы в Teacher Army ищем способы помогать начинающим разработчикам достигать высот. И в этот раз открыли возможность пройти тестовое собеседование. Что это такое? Это собеседование по стандартам индустрии, во время которого мы проверим ваши знания, а после него дадим подробную обратную связь.

Так же мы дадим рекомендации, как максимально эффективно проработать эту информацию и быстро подтянуть свои знания. Дополним ссылками на статьи, видео и доклады которые помогут сделать это максимально эффективно.

Подробно все расписано на странице Интервью. Переходите по ссылке, записывайтесь на собес. Будет круто!


Николай Роботов

06.03.2022

Читать полностью

Что учить фронтенд-разработчику в 2022 году

Новый год - новые переживания. Что же учить начинающему фронтенд разработчику в 2022 году? Из каждого утюга летит, что надо знать последний React, новый Vue, какой-нибудь стейт менеджер, а лучше два и отличия между ними. Препроцессоры, полифилы, сборщики, библиотеки, шаблонизаторы. Что там ещё.. UI-киты, паттерны проектирования, алгоритмы сортировки, алгоритмы обхода бинарного дерева. Обсервер, pub-sub, proxy. Итераторы, генераторы. Ах, да, евент луп, SOLID. А так же что будет, если в адресной строке написать адрес ресурса и нажать ентер.

Очень много. Просто невыносимо много. И наверняка, кто-то добавит сюда что-то ещё. Правда ведь добавит. Можно расширять этот список до бесконечности. Как и учиться можно тоже до бесконечности. И считать, что ещё не готов идти на собес, потому что так мало знаешь. Так что же на самом деле нужно учить в 2022 году, чтобы голова осталась на месте?

Для начала нужно понять, что ты учил в 2021 году. Подумай об этом. Может нужно посидеть, повспоминать. А лучше выписать всё это на листочек. Потом добавь напротив каждого элемента уровень знания от нуля до трех, где три это знаю хорошо, без помощи документации. Два знаю хорошо, но надо подсматривать в доку. Один не вспомню, если не загляну. Ноль - просто знаю, что есть, но не пробовал. Отлично, идём дальше.

Теперь добавь столбец, почему ты начал это учить. Причиной мог послужить учебный курс, наставник, статья, подкаст, какой-нибудь роадмап или просто неведомое желание. Если не помнишь, то напиши undefined.

Далее нужно добавить столбец, как часто это приходится применять. На собесах, в личных проектах, на работе, где угодно. Так же используй значение от 0 до 3.

Возможно ещё стоит указать тип, либа, часть языка, фреймворк, но совсем не обязательно.

А теперь будем отвечать на вопрос, что же учить в 2022 году. Учить нужно то, что нужно. А что не нужно, учить не обязательно. Посмотри на свою табличку. Отсортируй её по важности, то есть по частоте использования. Затем по знаниям. Вот оно. Нам нужны важные вещи, в которых ты ещё плаваешь. Это настоящая цель. Не нужно распыляться на то, что пишут в Твиттере или чему пророчат светлое будущее или называют очередной убийцей очередного реакта. Вот когда эти пророчества произойдут, тогда и обратим на это внимание. А пока разберемся с важными и реальными вещами. Укрепим свои знания. Сложно пройти собес, если плаваешь в теме, даже если таких тем много. Куда проще, если есть уверенные знания. Пусть не во всём, но они надежные. Потому что когда собеседующий получает уверенные ответы на часть вопросов, а на какие-то вопросы то, что ты об этом не знаешь, то он может предположить, что ты в них сможешь достаточно быстро разобраться. Ведь в этих ты разобрался.

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

Не бывает профессионалов во всём. Не зазорно быть профессионалом небольшого круга технологий, инструментов или даже методов массива. Потому что это только начало. Начало успешной карьеры и профессионального опыта.


Олег Акинин

17.02.2022

Читать полностью

Три истории

История первая

Когда я только пришёл в индустрию, мне очень сильно помогал мой друг. Я устроился тестировщиком, со слабым представлением о разработке. Знал немного про переменные, циклы и функции, а на объектах уже плыл. И вот Слава не пожалел своего времени и рассказывал мне самую необходимую информацию про js. Про работу с DOM, события, классы, наследование. Через некоторое время я начал писать простой код. Потом более сложный. А спустя год пополнил штат программистов в компании. Спустя несколько лет стал тимлидом. А потом, переехав в Питер, уже сам преподавал js в htmlacademy.

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

Иногда нужно совсем чуть-чуть. Иногда нужно очень много. Но помощи и поддержки даже одного человека будет достаточно, чтобы справиться с любыми трудностями в обучении программированию.

История вторая

Мы сидели с Игорем у меня на кухне и разговаривали за жизнь. И решили, что Игорю надо начать программировать. Я уже три года занимался разработкой и кайфовал. Самое сложное у меня было позади и теперь я получал истинное наслаждение от своей работы. Почему бы Игорю не кайфовать так же, подумали мы? И начали заниматься. Каждую субботу мы встречались и я ему что-то рассказывал, показывал. Скидывал статьи, предлагал задачи. А на неделе проводил код ревью. Хм.. не сильно отличается от того, как проходит у меня сейчас, если подумать. Но не буду отвлекаться. Вернёмся к Игорю.

Я не помню точно, сколько времени мы так занимались, но в итоге Игорь работает программистом. Не знаю, кайфует ли он сейчас, может уже выгорел к чертям. Шесть лет прошло как никак. Но раньше точно кайфовал :) Ну а если выгорел, то что? Да ничего особенного. Подзабил(это я про работу), подышал и снова все в кайф. Ну вектор может меняешь.

Я не знаю, хотелось ли мне вернуть типа долг Славе или мне просто хотелось, чтобы на одного программиста стало больше. Чтобы у друга была интересная оплачиваемая работа, от которой можно кайфовать. Но то, что я сам получал большое удовольствие от процесса это факт.

Страна жаждет угля, мир ждёт героев, всем нужны программисты. А если ты уже он, то легко можешь сделать +1. И от этого будет всем хорошо. И тебе, и твоему трейни. У тебя есть опыт, у него желание. Поделись с ним, это круто.

История третья

Уже больше года я занимаюсь индивидуальным наставничеством. До этого делал курсы в htmlacademy. Вел поток в OneBootcamp. Потом вернулся в разработку. Делиться знаниями очень понравилось - это здорово их структурирует у тебя в голове, находит пробелы. А ещё и учишься сам у своего подопечного. Но вот проблема, те площадки для наставничества, которые я видел, вместе с возможностью давали и ограничения. В частности на программу и формат.

Мне нравится, когда нет программы, которую кто-то спустил снизу. Особенно я понял это, когда вёл курс в OneBootcamp. Есть только цель. Цель, или цели, озвучивает студент. Программу ты продумываешь сам. Определяешь оптимальный маршрут на основе целей, навыков и опыта студента и вперёд.

Когда я только решил этим заниматься, я не думал, что это так кайфово - созваниваетесь, разговариваете, что-то обсуждаете. Если нужно, то можно и лекцию прочитать. Если нужно, то можно просто послушать. Подбодрить и поддержать, научить определять синдром самозванца и как его побеждать. Можно обсудить новости индустрии, которые могут быть полезны подопечному. Разбираете сложности, с которыми он столкнулся со времени последнего созвона. Где-нибудь в середине советуешь книжку. Или конкретную главу, под задачу. Дел у людей и так много, кто-то не успевает, кто-то ленится читать. А по небольшому совету или когда это вписывается в цель, люди читают охотнее.

Иногда отлично подходит лайвкодинг или парное программирование. Это, как правило, занимает больше всего времени и можно не успеть с остальным. Все таки нет задачи в программировании, которую можно решить за пятнадцать минут, как ни крути =) На такие сессии лучше договариваться отдельно и выделять на них минут сорок, тогда можно спокойно успеть сделать намеченное.

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

Наставничать круто и не так сложно или страшно, как может показаться. Это приносит пользу тебе, твоему подопечному, индустрии и может даже экологии. Да точно экологии, чувак меньше сидит за компом в поисках решения, перенимая твой опыт делает всё как минимум на четверть быстрее. А может даже и в два раза)) Про всю пользу можно отдельный пост написать.

Если тебе хочется начать наставничать, то приглашаю к нам в Teacher Army. Мы предоставляем инструменты профессионалам, которые хотят делиться своими знаниями по своим правилам. Помогаем новичкам находить вас и перенимать ваш опыт. Программирование это кайф. Наставничество это кайф. Давайте кайфовать вместе! Напиши мне в личку или в телеграм https://t.me/kicumkicum и я расскажу обо всём подробнее.


Олег Акинин

31.12.2021

Читать полностью

Немного о наставниках

Кто такой наставник

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

Выбрав профессиональное развитие в программировании у вас два пути:

  • обучаться самостоятельно, набивать шишек и набираться опыта. Этот путь не быстрый. Но при усидчивости приведет к результату;
  • путь более быстрый - обучение и работа под присмотром наставника - опытного коллеги, который прошел путь и готов поделиться опытом и знаниями. Наставник подскажет, на что обратить внимание, что изучить, на что не стоит тратить время и какие шаги пропустить.

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

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

Мастер восточных единоборств Брюс Ли как то сказал: "Учитель не открывает истины, он — проводник истины, которую каждый ученик должен открыть для себя сам. Хороший учитель — лишь катализатор."

Мы изменим фразу и скажем: "Хороший наставник не открывает истины, он позволяет вам находить ответы, где раньше вы их не видели".

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

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

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

Так же наставник может помочь и в решении ситуативных проблем. Например, при создании сайта у вас некорректно отображаются блоки в мобильной версии. Решения, которые вы знаете, не помогают. Тогда, вы пишите вопросы и опробованные решения задачи. Наставник помогает найти первопричину некорректной работы сайта и объяснит новый способ решения задачи. И под его присмотром вы эффективно его реализуете.

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

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

Как найти наставника

Мы уже выяснили кто такой наставник и в каких вопросах он может помочь специалисту.

Сегодня узнаем, где искать наставника программисту!

Самый простой вариант - устроиться на работу программистом в крупную компанию и попросить опытного коллегу позаниматься с вами. Правда не всегда коллеги хотят делиться своим опытом. Ну что, им жалко что ли?! Конечно нет. Просто им тоже надо работать.

Но кроме этого есть еще варианты:

  1. Обучающие курсы и школы, где преподаватели и наставники будут помогать осваивать новые знания. Но часто это не бюджетно и занимает много времени.
  2. Профессиональные сообщества (форумы, паблики, неспециализированные сервисы). Вариант бюджетный, но поиски занимают много времени и могут так и не закончиться успехом.
  3. Специализированные сервисы, где по вашему запросу и целям, подбирают наставника, который будет подходить вам. Один из таких сервисов Teacher Army. Отправьте заявку и с вами свяжется представитель компании. Узнав у вас цели и задачи, сервис подбирает наставника. В процессе работы наставник направляет, мотивирует и помогает выстроить траекторию действий, чтобы вы добились цели, которую перед собой поставили.

Какой бы вариант поиска наставника вы не выбрали, помните, результат только в ваших руках! Наставник только поможет скорректировать путь в решении задачи.


Мария Василенко

10.11.2021

Читать полностью