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

Начните с Recoiljs, создавая приложение Fantasy в реактивном родном

Сложность вашего приложения стало последовательно. Чтобы держать вещи организованными, вы разделите свой код в … Помечено реагированием, реактивным, JavaScript.

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

Вам нужно глобальное государственное управление!

Из ваших исследований по теме «Лучшая глобальная государственная библиотека управления», вы заключаете, что вам нужно интегрировать Redux Отказ Единственное, что вы помните о Redux, – это время, когда вы проходили курс по реагированию или реагирующим на родном, и был модуль о redux. В то время он чувствовал себя довольно ясно, но через неделю вы знали столько о redux, как я делаю о Regex.

Я не могу отрицать популярность, масштаб и зрелость redux, но человек он преодолел. Действия, Экги Создатели, Редукторы, Селекторы, Сага, Thunk 🤯

Простые альтернативы – это контекст API. Легко учиться, он выходит из коробки, и это сделает свою работу. Это отличное и простое решение, которое хорошо работает для небольших проектов.

С другой стороны, контекст API был разработан для вещей, которые не часто меняются (например, тема, варианты, предпочтения). Это не очень оптимально, когда дело доходит до данных, которые меняются очень часто.

Тогда какая альтернатива?

Отдача работает и думает, как реагировать!

Recoil.js Экспериментальная библиотека, разработанная командой Facebook с простотой и совместимостью. Он был разработан специально для реакции, и это делает его супер легко начать и интегрировать его в свой реактивный или реагировать нативный проект. Он чувствует себя родным, потому что они держали API, семантику и поведение как можно более реактивно.

В отдаче, есть 2 главных строительных блока: атомы и селекторы.

Атомы являются общим государством; отдельные единицы государства.

Селекторы являются чистыми функциями, которые потребляют атомы (или другие селекторы), обрабатывают данные и возврат ее. Они используются для создания производных данных.

Потоки данных из атомы через Селекторы вниз в реактивный компонент.

Атомы

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

Атомы создаются с использованием функции атома:

const fontSizeState = atom({
  key: 'fontSizeState',
  default: 14,
});

Читать и написать атом из компонента, мы используем крючок под названием Userecilstate () Отказ Это так же, как React’s Usestate () Но сейчас государство может быть разделено между компонентами:

const [fontSize, setFontSize] = useRecoilState(fontSizeState);

Селекторы

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

Селекторы используются для расчета производных данных, основанных на состоянии.

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

Селекторы определяются с помощью функции селектора:

const fontSizeLabelState = selector({
  key: 'fontSizeLabelState',
  get: ({ get }) => {
    const fontSize = get(fontSizeState);
    const unit = 'px';

    return `${fontSize}${unit}`;
  },
});

Селекторы можно прочитать, используя userecoilvalue () , который принимает атом или селектор в качестве аргумента и возвращает соответствующее значение.

const fontSizeLabel = useRecoilValue(fontSizeLabelState);

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

Мы собираемся построить Фэнтезийный спорт приложение, похожее на Игры УЕФА Отказ Пользователи смогут создать команду своей мечты, выбрав игроков из списка.

Пользовательские истории приложения: «Как пользователь, я хочу …

  • Смотреть все доступные игроки
  • Фильтруйте игроков на основе позиции они играют
  • быть в состоянии добавить/удалить игроков в мою команду
  • Смотрите мою команду на поле
  • Смотрите количество игроков и имеющийся бюджет для покупки игроков

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

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

Отправная точка

Я подготовил UI для нашего приложения, поэтому мы можем сосредоточиться только на отдаче. Я предлагаю открыть пропущенную закуску на Snack.expo.io , чтобы иметь возможность просматривать все компоненты, из которых оно сделано из.

Важные компоненты, с которыми мы собираемся работать, являются:

  • Компоненты/Поле Отображает поле со всеми моими игроками на своих позициях
  • Компоненты/PlayerListiteM Оказывает информацию о одном игроке, в списке всех игроков
  • Компоненты/фильтры Оказывает фильтры позиции игрока
  • Компоненты/Teamstats Статистика о команде, которую вы можете увидеть поверх экрана (количество игроков, оставшийся бюджет)

Установка и настройка отдачи

Чтобы установить отдачу, просто запустите пряжа добавляет отдачу или NPM установить отдачу

Если вы работаете над вышеупомянутой закуски, вы можете добавить его прямо в package.json файл как «Отдача»: «^ 0,3.1»

Реконструировать

Компоненты, которые используют отдохнуть государству нужны Recoilroot появиться где-то в родительском дереве. Хорошее место, чтобы поставить это в вашем корневом компонент ( app.js ). Я создал и экспортировал отдельный RecoilApp Компонент, чтобы иметь возможность обернуть мое приложение с Реконструировать

export default function RecoilApp() {
  return (
    
      
    
  );
}

Игроки Данные

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

В новом файле атомы/игроки.js Давайте создадим штат наших игроков, используя атом функция.

import { atom } from 'recoil';

import players from '../assets/players';

export const allPlayersState = atom({
  key: 'allPlayersState',
  default: players,
});

Чтобы потреблять эти данные, мы будем использовать userecoilvalue () функция для восстановления значения состояния.

// App.js
import { useRecoilValue, RecoilRoot } from 'recoil';
import { allPlayersState } from './atoms/Players';

function App() {
  const players = useRecoilValue(allPlayersState);

  return (
    ...
  )
}

Фильтры

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

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

// atoms/Players.js

export const positionFilterState = atom({
  key: 'positionFilterState',
  default: [],
});

Теперь давайте потребним это состояние в Компонент/filter.js используя Userecilstate Отказ Это очень похоже на нормальное Уместите от реагирования.

Если позиция выбрана (включена в массив фильтра), мы покажим его другим цветом в интерфейсе UI.

При нажатии на фильтр положения мы проверим, придется ли мы добавить его в массив или удалить его.

// components/Filter.js

import { useRecoilState } from "recoil";
import { positionFilterState } from "../atoms/Players";

const Filters = () => {
  const [positionFilter, setPositionFilter] =
    useRecoilState(positionFilterState);

  const onFilterPress = (position) => {
    setPositionFilter((curPositionFilter) => {
      if (curPositionFilter.includes(position)) {
        return curPositionFilter.filter((pos) => pos !== position);
      } else {
        return [...curPositionFilter, position];
      }
    });
  }

  const isSelected = (position) => {
    return positionFilter.includes(position);
  }

  return (
    ...
  )

Фильтрация игроков

Для отображения фильтрованных игроков в списке на основе выбранных фильтров мы будем использовать отдачу селектор Отказ Отфильтрованные плееры представляют собой производные данные, которые будут зависеть от 2 атомов: AllPlayersState и позиционерныйФитльстат Отказ

// atoms/Players.js
import { atom, selector } from 'recoil';

export const filteredPlayers = selector({
  key: 'filteredPlayers',
  get: ({ get }) => {
    const players = get(allPlayersState);
    const filters = get(positionFilterState);
    return players.filter(
      (player) => filters.length === 0 || filters.includes(player.position),
    );
  },
});

Теперь мы можем заменить AllPlayersState Атом с FilteredPlayers Селектор в App.js отображает фильтрованные плееры в списке.

// App.js
import { allPlayersState, filteredPlayers } from './atoms/Players';

function App() {
  const players = useRecoilValue(filteredPlayers);
  ...
}

Моя команда

Чтобы иметь возможность выбрать игроков и добавить их в команду, мы создадим новый атом MyPlayersState . Это будет массив игроков.

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

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

// atoms/MyTeam.js

import { atom, selector } from 'recoil';

export const myFormationState = atom({
  key: 'myFormation',
  default: {
    FWD: 3,
    MID: 3,
    DEF: 4,
    GCK: 1,
  },
});

export const myPlayersState = atom({
  key: 'MyPlayersState',
  default: [],
});

const positions = ['FWD', 'MID', 'DEF', 'GCK'];

export const myPlayersByPosition = selector({
  key: 'myPlayersByPosition',
  get: ({ get }) => {
    const players = get(myPlayersState);
    const formation = get(myFormationState);

    const groupedPlayers = {};

    positions.forEach((position) => {
      groupedPlayers[position] = players.filter((p) => p.position === position);
      // fill with null values, up to the amount of expected players from formation
      for (
        let i = groupedPlayers[position].length;
        i < formation[position];
        i++
      ) {
        groupedPlayers[position].push(null);
      }
    });

    return groupedPlayers;
  },
});

Добавить/удалить игроков в мою команду

Чтобы добавить и удалить выбранные игроки в моей команде, мы обновим PlayerListitem Компонент, который оказывает один игрок в списке всех игроков.

Мы потребляем состояние ReCoil, которое содержит все выбранные игроки: const [myplayers, (myplayersstate);

Давайте реализуем onpress Функция, которая будет изменять состояние соответственно. Если щелчок проигрывала уже в моей команде, то мы захочем удалить его из штата. В противном случае мы хотим добавить его в команду, но прежде чем добавлять его, мы также должны убедиться, что в команде есть пустое место. Например, если мы нажимаем на защитника, и наше формирование составляет 3-3-4, что означает, что мы можем иметь максимум 4 защитников, мы сможем добавить игрока только в том случае, если уже выбрано менее 4 защитников.

Не забудьте заменить корню Вид компонента с Нажатием и прикрепить onpress мероприятие. Также, добавив этот условный стиль {backgroundcolor: Увидел? « # D170DB ': «Белый»}, к Нажатием Строка станет фиолетовым, если игрок выбран.

// components/PlayerListItem.js
import { useRecoilState, useRecoilValue } from 'recoil';
import { myFormationState, myPlayersState } from '../atoms/MyTeam';

const PlayerListItem = ({ player }) => {
  const [myPlayers, setMyPlayers] = useRecoilState(myPlayersState);
  const myFormation = useRecoilValue(myFormationState);

  const numberOfPlayersOnPos = myPlayers.filter(
    (p) => p.position === player.position,
  ).length;

  const onPress = () => {
    setMyPlayers((curPlayers) => {
      if (curPlayers.some((p) => p.id === player.id)) {
        return curPlayers.filter((p) => p.id !== player.id);
      }
      // CHECK if it's possible to add
      if (numberOfPlayersOnPos < myFormation[player.position]) {
        return [...curPlayers, player];
      }
      return curPlayers;
    });
  };

  const isSelected = myPlayers.some((p) => p.id === player.id);

  return (
    
      ...
    
  );
};

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

Показать мои игроки на поле

Давайте объединим вышеуказанную функцию выбора игроков в моей команде, с отображением выбранных игроков на поле. Мы редактируем Компоненты/field.js файл и заменит локальный Игроки Кукурный объект со значением MyPlayersbization селектор.

// components/Field.js
import { useRecoilValue } from "recoil";
import { myPlayersByPosition } from "../atoms/MyTeam";

const Field = () => {
  const players = useRecoilValue(myPlayersByPosition);

  return (
    ...
  );
};

Чтобы отобразить имя проигрывателя на поле, мы добавим следующий условный рендер в Fieldplayer.js Линия 22.

{
  player ? player.name : position;
}

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

Статистика команды

Последний шаг - это рассчитать и представлять некоторые статистические данные о команде. Мы сосредоточимся на 2 значения: количество игроков, общая стоимость игроков;

Мы рассчитаем эти 2 значения, используя 2 Селекторы что мы добавим к атомы/myteam.js.

// atoms/MyTeam.js

export const numberOfPlayers = selector({
  key: 'numberOfPlayers',
  get: ({ get }) => {
    return get(myPlayersState).length;
  },
});

export const valueOfPlayers = selector({
  key: 'valueOfPlayers',
  get: ({ get }) => {
    return get(myPlayersState).reduce((acc, player) => acc + player.price, 0);
  },
});

С помощью этого реализованы, мы можем потреблять эти значения в Компоненты/Teamstats компонент. Мы покажим количество игроков в команде, и оставшийся бюджет (100 млн долларов - общая стоимость игроков);

// components/TeamStats.js
import { useRecoilValue } from "recoil";
import { numberOfPlayers, valueOfPlayers } from "../atoms/MyTeam";

const TeamStats = () => {
  const nofPlayers = useRecoilValue(numberOfPlayers);
  const value = useRecoilValue(valueOfPlayers);

  return (
    ...
    {nofPlayers} / 15
    ...
    ...
    
      ${((100_000_000 - value) / 1_000_000).toFixed(1)}m
    
    ...
  );
};

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

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

Полный исходный код вышеуказанного приложения можно найти на моем Github Отказ

Проверьте видео версию этого поста на моем YouTube Channel Отказ

И, наконец, оставайся увлажненным и написать чистый клон!

Оригинал: "https://dev.to/vadimnotjustdev/get-started-with-recoiljs-by-building-a-fantasy-app-in-react-native-598b"