Сокращение шаблона приложения React/Redux с помощью require.context и структуры модуля


require.context позволяет нам импортировать несколько файлов, используя регулярное выражение

Перейти к профилю Гонсало Поццо

Гонсало ПоццоЗаблокированоUnblockFollowFollowing

20 октября 2018 г.

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

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

Вот почему сегодня мы собираемся сосредоточиться на этих двух моментах.

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


Создание нашего приложения

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

npx create-react-app reducing-boilerplate

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

Мы в папке reducing-boilerplate который создал приложение create-реагировать, и мы запускаем:

npm start

В браузере откроется новая вкладка, и мы увидим следующий экран:


Приложение работает на


Создаем наш первый модуль

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

У нас будут редукторы, помощники API и компоненты, которые имеют отношение к шуткам, кажется, это хорошая возможность создать módulo

модули

Давайте создадим папку modules в src. Внутри мы создадим папку joke

Модули названы в единственном числе, так как это относится к функциональности независимо от количества.

В пределах joke давайте создадим файлы api.js, reducers.js и папка components с файлом JokesManager.js

наша папка modules это будет выглядеть так:

.└── modules/ └── joke/ ├── api.js ├── reducers.js └── components/ └── JokesManager.js

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

Установка и настройка Redux

Установим необходимые зависимости:

npm install redux react-redux --save

Мы создаем папку db в пределах srcс файлами reducers.js (наш корневой редуктор), store.js (редукционная конфигурация), utils.js (утилита, которую мы увидим через некоторое время).

.└── db/ ├── store.js ├── reducers.js └── utils.js

/db/utils.js

requireAll отвечает за извлечение необходимой нам информации из того, что он возвращает require.context

export const requireAll = ctx =>
  ctx
    .keys()
    .map(ctx)
    .map(m => m.default)
    .filter(Boolean);

Сильно разбирать нет смысла, так как это почти копипаста документации вебпака

БД/reducers.js

Это будет перебирать папку modules и все его подкаталоги в поисках файлов с именем reducers.js и объединит их в один объект. Это означает, что каждый раз, когда мы создаем модуль и добавляем новый файл reducers.js нам не придется вручную добавлять его в наш корневой редуктор!

import {requireAll} from "./utils";

export default Object.assign(
  {},
  ...requireAll(require.context("../modules", true, /reducers\.js$/))
);

Если бы мы хотели добавить еще один редуктор вручную, мы могли бы сделать это, добавив новую запись в Object.assign

БД/store.js

Мы создаем редукционный магазин, используя наш корневой редуктор

import {createStore, combineReducers} from "redux";

import reducers from "./reducers";

export default createStore(combineReducers(reducers));

index.js

Мы собираемся обернуть все наше приложение Provider из react-redux, проходящего через props, магазин, который мы только что создали:

import React from "react";
import ReactDOM from "react-dom";
import {Provider} from "react-redux";

import App from "./App";

import store from "./db/store";

import "./index.css";

ReactDOM.render(
  <Provider store={store}>
    <App />
  </Provider>,
  document.getElementById("root")
);

Внедрение нашего модуля

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

модули/шутка/api.js

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

const URL = "

export default {
  random: {
    fetch: () =>
      fetch(`${URL}/random`)
        .then(res => res.json())
        .then(joke => joke.value)
  }
};

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

/modules/шутка/reducers.js

Наше приложение может:

  • Запустите запрос API, который отключит кнопку получения шутки.
  • Добавьте в список новую шутку, которая снова активирует кнопку «Получить шутку».
  • Удалить шутку из списка.
const initialState = {
  joke: {
    status: "init",
    list: []
  }
};

export default {
  joke: (state = initialState.joke, action) => {
    switch (action.type) {
      case "FETCH_JOKE": {
        return {
          ...state,
          status: "pending"
        };
      }

case "ADD_JOKE": {
        return {
          ...state,
          list: state.list.concat(action.payload),
          status: "init"
        };
      }

case "DELETE_JOKE": {
        return {
          ...state,
          list: state.list.filter(joke => joke !== action.payload)
        };
      }

default:
        return state;
    }
  }
};

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

export default {
  joke: (state, action) => ...,
  selectedJoke: (state, action) => ...
}

Если вам не нравится иметь несколько редукторов в одном файле, вы можете создать их внутри папки. reducers и импортировать их в reducer.js

модули/шутка/компоненты/JokesManager.js

Наш компонент будет:

  • Показать список шуток
  • Есть кнопка для удаления каждой шутки
  • Есть кнопка, чтобы получить новую шутку
import React from "react";
import {connect} from "react-redux";

import jokeApi from "../api";

const JokesManager = ({jokes, loading, getJoke, deleteJoke}) => (
  <div>
    <ul>
      {jokes.map(joke => (
        <li key={joke}>
          {joke}
          <button type="button" onClick={() => deleteJoke(joke)}>
            Delete
          </button>
        </li>
      ))}
    </ul>
    <button type="button" onClick={getJoke} disabled={loading}>
      Get joke
    </button>
  </div>
);

export default connect(
  ({joke}) => ({
    jokes: joke.list,
    loading: joke.status === "pending"
  }),
  dispatch => ({
    getJoke: () => {
      dispatch({type: "FETCH_JOKE"});

return jokeApi.random
      .fetch()
      .then(joke => dispatch({type: "ADD_JOKE", payload: joke}));
    },
    deleteJoke: joke => dispatch({type: "DELETE_JOKE", payload: joke}),
  })
)(JokesManager);

С помощью нашего модуля

Давайте использовать JokesManager в нашем приложении.

App.js

import React from "react";

import JokesManager from "./modules/joke/components/JokesManager";

const App = () => (
  <div>
    <h1>Chistes de Chuck Norris</h1>
    <JokesManager />
  </div>
);

export default App;

И конечный результат:


Большой!


Ресурсы


Другой

  • Мы создаем наше приложение с помощью create-react-app.
  • Мы создали модуль и необходимые нам файлы.
  • Добавляем и настраиваем Redux с помощью require.context
  • Мы используем наш модуль в приложении.

Если вам понравилось или было полезно, поделитесь с тем, кому это может быть полезно, если вам что-то показалось не так, скажите!

Похожие записи

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *