Использование TypeScript (китайский) в Create-React-App

TypeScript модульный тест React.js Redux

TypeScript React Starter

Это краткое руководство покажет вам, как интегрировать TypeScript сReactСвязаться.
По окончании обучения вы получите:

  • Проект, использующий как React, так и TypeScript
  • использоватьTSLintпроверить код
  • использоватьJestа такжеEnzymeтест, и
  • пройти черезReduxстатус управления

мы будем использоватьcreate-react-appИнструменты для быстрого создания проектов.

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

Установите приложение для создания реакции

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

npm install -g create-react-app

Создайте свой новый проект

Мы создадимmy-appновый проект:

create-react-app my-app --scripts-version=react-scripts-ts

react-scripts-tsЕго можно понимать как плагин, который вводит TypeScript в стандартный конвейер проекта создания-реакции-приложения.

Теперь макет вашего проекта выглядит так:

my-app/
├─ .gitignore
├─ node_modules/
├─ public/
├─ src/
│  └─ ...
├─ package.json
├─ tsconfig.json
└─ tslint.json

Примечания:

  • tsconfig.jsonСодержит специфичные для TypeScript параметры конфигурации для нашего текущего проекта.
  • tslint.jsonСохраните настройки инструмента обнаружения,TSLint, будет использовано.
  • package.jsonСодержит наши зависимости, а также некоторые из них, которые мы можем использовать для тестирования, предварительного просмотра, сборки.appИспользуйте сочетания клавиш для команд.
  • publicСодержит некоторые вещи, которые мы планируем развернуть, напримерHTMLТакие статические ресурсы, или изображения.В этой папке, кромеindex.htmlЭтот файл, другие можно удалить.
  • srcСодержит наш код TypeScript и CSS.index.tsxЯвляется强制性входной файл.

запустить проект

Запустить этот проект так же просто, как запустить.

npm run start

Это заставит насpackage.jsonуказано вstartСкрипт, когда мы сохраним файл, вызовет сервис для перезагрузки интерфейса (горячая перезагрузка).
Обычно служба работает наhttp://localhost:3000, но должен автоматически открываться для вас.

Плотный опрос позволяет нам быстро просматривать изменения.

Тестовые задания

Тестирование — это тоже просто команда:

npm run test

Эта команда запускает Jest, очень полезный инструмент тестирования, для всех файлов, расширение которых заканчивается.test.ts or .spec.ts.
как бегnpm run startКак и команда, Jest запустится автоматически, как только обнаружит изменение.
Вы можете работать одновременно, если хотитеnpm run startа такжеnpm run test, поэтому вы можете проверить свои изменения во время предварительного просмотра.

Создать производственную версию

использовался в то времяnpm run startПри запуске проекта мы не занимались оптимизацией упаковки.
Как правило, мы ожидаем, что код, который мы отправляем нашим клиентам, будет как можно короче.
некоторым нравитсяminificationТакая оптимизация может достичь этого, но требует больше времени.
Мы называем это производственной сборкой (в отличие от开发环境строить).

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

npm run build

это будет./build/static/js and ./build/static/cssкаталог, создайте оптимизированные сборки JS и CSS соответственно.

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

Создать компонент

мы напишемHelloкомпонент.
Компонент примет имя, которое мы хотим приветствовать (назовем егоname) и необязательное количество восклицательных знаков, чтобы сделать некоторые завершающие токены (enthusiasmLevel, Добро пожаловать).

Мы написали что-то вроде этого<Hello name="Daniel" enthusiasmLevel={3} />, компонент будет отображать что-то вроде<div>Hello Daniel!!!</div>.
еслиenthusiasmLevelЕсли не указано, компонент будет отображать восклицательный знак по умолчанию.
еслиenthusiasmLevelда0или отрицательный, он выдаст ошибку.

мы напишемHello.tsxдокумент:

// src/components/Hello.tsx

import * as React from 'react';

export interface Props {
  name: string;
  enthusiasmLevel?: number;
}

function Hello({ name, enthusiasmLevel = 1 }: Props) {
  if (enthusiasmLevel <= 0) {
    throw new Error('You could be a little more enthusiastic. :D');
  }

  return (
    <div className="hello">
      <div className="greeting">
        Hello {name + getExclamationMarks(enthusiasmLevel)}
      </div>
    </div>
  );
}

export default Hello;

// helpers

function getExclamationMarks(numChars: number) {
  return Array(numChars + 1).join('!');
}

Обратите внимание, что мы определяемPropsИнтерфейс используется для указания свойств, которые получит компонент.
nameдолжен бытьstringтип иenthusiasmLevelявляется необязательнымnumberтипа (вы можете получить?Зная это, мы пишем его после его имени).

мы кладемHelloНаписан как компонент функции без сохранения состояния (компонент функции без состояния, называемый SFC).
специфический,Helloявляется функцией и принимаетPropsобъект и деконструировать его.
если нашPropsобъект не предоставленenthusiasmLevelэто свойство, по умолчанию будет1.

Пишите компоненты через функции, даReact позволяет нам создавать компоненты) одним из двух основных способов.
Если хотите, мытакже можетЗапишите это как класс следующим образом:

class Hello extends React.Component<Props, object> {
  render() {
    const { name, enthusiasmLevel = 1 } = this.props;

    if (enthusiasmLevel <= 0) {
      throw new Error('You could be a little more enthusiastic. :D');
    }

    return (
      <div className="hello">
        <div className="greeting">
          Hello {name + getExclamationMarks(enthusiasmLevel)}
        </div>
      </div>
    );
  }
}

Когда ваш компонент содержит состояниеЗанятия очень эффективные.
Но нам не нужно рассматривать состояние в этом примере — на самом деле мы указываем, что этоobjectвведитеReact.Component<Props, object>, поэтому написание ПФС имеет тенденцию быть более утонченным.
Состояние локального компонента более полезно на практическом уровне при создании общих элементов пользовательского интерфейса, которые могут использоваться совместно библиотеками.
В течение жизненного цикла нашего приложения мы будем пересматривать приложение, как пройтиReduxУправляйте общим состоянием.

Теперь, когда мы написали наш компонент, давайте углубимся вindex.tsxи использовать<Hello ... />метод рендеринга, переопределить<App />Метод рендеринга компонента.

Во-первых, мы импортируем его в начало файла:

import Hello from './components/Hello';

затем измените нашrenderпередача:

ReactDOM.render(
  <Hello name="TypeScript" enthusiasmLevel={10} />,
  document.getElementById('root') as HTMLElement
);

утверждение типа

Последнее, на что мы собираемся обратить внимание в этом разделе, — это строкаdocument.getElementById('root') as HTMLElement.
Это написание являетсяутверждение типазвонить, иногда звонитьcast.
Это очень полезный способ сообщить TypeScript, когда вы знаете больше о реальном типе выражения, чем о проверке типа.

Причина, по которой нам нужно сделать это в данном случае, заключается в следующем.getElementByIdТип возвращаемого значенияHTMLElement | null.
Проще говоря,getElementByIdданнымidКогда элемент не найден, вернитеnull.
давайте предположимgetElementByIdвсегда удается, поэтому нам нужно убедить TypeScript в этом, используяasграмматика.

TypeScript также имеет завершающий синтаксис «bang» (!), будет удалено из предыдущего выраженияnullа такжеundefined.
поэтому мытакже можетнапиши вот такdocument.getElementById('root')!, но в данном случае мы хотим быть более явными.

Добавьте стиля 😎

Стилизовать компонент с помощью наших настроек очень просто.
украсить нашHelloкомпонент, мы можем создать файл CSS вsrc/components/Hello.cssПод содержанием.

.hello {
  text-align: center;
  margin: 20px;
  font-size: 48px;
  font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
}

.hello button {
  margin-left: 25px;
  margin-right: 25px;
  font-size: 40px;
  min-width: 50px;
}

Инструменты, используемые create-react-app (а именно, Webpack и различные загрузчики), позволяют нам импортировать только интересующие нас таблицы стилей.
Когда наша сборка запускается, любой импортированный.cssФайлы будут объединены в один выходной файл.
Итак, вsrc/components/Hello.tsx, мы добавим следующий импорт.

import './Hello.css';

Пройти тест по написанию шуток

МыHelloКомпоненты имеют определенные допущения. Давайте еще раз повторим, что они из себя представляют:

  • когда мы пишем это<Hello name="Daniel" enthusiasmLevel={3} />, компонент отображает что-то вроде<div>Hello Daniel!!!</div>.
  • еслиenthusiasmLevelЕсли не указано, компонент должен отображать восклицательный знак.
  • еслиenthusiasmLevelда0или отрицательный, он выдаст ошибку.

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

Но сначала давайте установим Enzyme.
Enzyme— это распространенный инструмент в экосистеме React, упрощающий написание предсказуемых тестов поведения компонентов.
По умолчанию наше приложение включает библиотеку под названием jsdom, которая позволяет нам имитировать модель DOM и тестировать ее поведение во время выполнения без браузера.
Enzyme похож, но основан на jsdom, чтобы упростить выполнение определенных запросов для наших компонентов.

давайте сделаем это开发时依赖Установить.

npm install -D enzyme @types/enzyme react-addons-test-utils

Обратите внимание, что мы устанавливаемenzymeтакже установлен@types/enzyme.
enzymeПакет относится к пакету, который содержит фактически работающий код JavaScript, в то время как@types/enzymeфайл объявления включения (.d.tsфайлы) и упрощает для TypeScript понимание того, как использовать Enzyme.
ты можешь начатьздесьУзнать больше о@typesЗнание пакетов.

Нам также необходимо установитьreact-addons-test-utils.
Этоenzymeнужный.

Теперь, когда мы настроили Enzyme, давайте начнем писать тесты!
Давайте создадимsrc/components/Hello.test.tsx, и тот, который мы создали ранееHello.tsxФайлы находятся в одном каталоге.

// src/components/Hello.test.tsx

import * as React from 'react';
import * as enzyme from 'enzyme';
import Hello from './Hello';

it('renders the correct text when no enthusiasm level is given', () => {
  const hello = enzyme.shallow(<Hello name='Daniel' />);
  expect(hello.find(".greeting").text()).toEqual('Hello Daniel!')
});

it('renders the correct text with an explicit enthusiasm of 1', () => {
  const hello = enzyme.shallow(<Hello name='Daniel' enthusiasmLevel={1}/>);
  expect(hello.find(".greeting").text()).toEqual('Hello Daniel!')
});

it('renders the correct text with an explicit enthusiasm level of 5', () => {
  const hello = enzyme.shallow(<Hello name='Daniel' enthusiasmLevel={5} />);
  expect(hello.find(".greeting").text()).toEqual('Hello Daniel!!!!!');
});

it('throws when the enthusiasm level is 0', () => {
  expect(() => {
    enzyme.shallow(<Hello name='Daniel' enthusiasmLevel={0} />);
  }).toThrow();
});

it('throws when the enthusiasm level is negative', () => {
  expect(() => {
    enzyme.shallow(<Hello name='Daniel' enthusiasmLevel={-1} />);
  }).toThrow();
});

Эти тесты очень простые, но вы должны уловить суть.

Добавить управление состоянием

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

Государственное управление в целом

React — полезная библиотека для создания составных представлений.
Однако в React нет средств для синхронизации данных между приложениями.
В случае компонентов React данные передаются через свойства к каждому указанному вами дочернему элементу.

Поскольку сам React не содержит встроенной поддержки управления состоянием, React использует такие библиотеки, как Redux и MobX.

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

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

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

Следующие разделы могут иметь крутую кривую обучения.
мы прямо советуем вамПознакомьтесь с Redux через его документацию..

Подготовьте почву для действий

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

Для наших целей мы добавим две кнопки для управления нашимHelloПопулярность компонента.

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

Добавляем Redux, сначала устанавливаемreduxа такжеreact-reduxи библиотеки их типов в качестве зависимостей.

npm install -S redux react-redux @types/react-redux

В этом примере нам не нужно устанавливать@types/reduxПоскольку у Redux уже есть собственный файл определения (.d.ts files).

Определить состояние нашего приложения

Нам нужно определить, как выглядит состояние, которое будет хранить Redux.
Для этого мы можем создатьsrc/types/index.tsxфайл, который будет содержать определения типов, которые могут использоваться в программе.

// src/types/index.tsx

export interface StoreState {
    languageName: string;
    enthusiasmLevel: number;
}

Наше намерениеlanguageNameбудет языком программирования, на котором написано это приложение (например, TypeScript или JavaScript) иenthusiasmLevelизменится.
Когда мы написали наш первый контейнер, мы увидим, почему мы намеренно сделали наше состояние немного отличным от наших реквизитов.

добавить действия

Давайте начнем с создания набора типов сообщений, на которые может отвечать наше приложение, вsrc/constants/index.tsx.

// src/constants/index.tsx

export const INCREMENT_ENTHUSIASM = 'INCREMENT_ENTHUSIASM';
export type INCREMENT_ENTHUSIASM = typeof INCREMENT_ENTHUSIASM;


export const DECREMENT_ENTHUSIASM = 'DECREMENT_ENTHUSIASM';
export type DECREMENT_ENTHUSIASM = typeof DECREMENT_ENTHUSIASM;

этоconst /typeШаблоны, которые позволяют нам использовать типы строковых литералов TypeScript доступным и поддающимся рефакторингу способом.

Далее мы будемsrc/actions/index.tsxСоздайте набор действий в , и конструктор действий.

import * as constants from '../constants'

export interface IncrementEnthusiasm {
    type: constants.INCREMENT_ENTHUSIASM;
}

export interface DecrementEnthusiasm {
    type: constants.DECREMENT_ENTHUSIASM;
}

export type EnthusiasmAction = IncrementEnthusiasm | DecrementEnthusiasm;

export function incrementEnthusiasm(): IncrementEnthusiasm {
    return {
        type: constants.INCREMENT_ENTHUSIASM
    }
}

export function decrementEnthusiasm(): DecrementEnthusiasm {
    return {
        type: constants.DECREMENT_ENTHUSIASM
    }
}

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

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

Здесь есть очевидный код стиля, поэтому вы всегда должны смотреть на такие вещи, какredux-actionsтакая библиотека.

добавить редуктор

Мы готовы написать наш первый редуктор!

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

Наш редуктор будет подsrc/reducers/index.tsx.

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

// src/reducers/index.tsx

import { EnthusiasmAction } from '../actions';
import { StoreState } from '../types/index';
import { INCREMENT_ENTHUSIASM, DECREMENT_ENTHUSIASM } from '../constants/index';

export function enthusiasm(state: StoreState, action: EnthusiasmAction): StoreState {
  switch (action.type) {
    case INCREMENT_ENTHUSIASM:
      return { ...state, enthusiasmLevel: state.enthusiasmLevel + 1 };
    case DECREMENT_ENTHUSIASM:
      return { ...state, enthusiasmLevel: Math.max(1, state.enthusiasmLevel - 1) };
  }
  return state;
}

Обратите внимание, что мы используемоператор распространения объекта (...state), что позволяет нам создать неглубокую копию состояния, заменив при этомenthusiasmLevel.
Стоит отметить, чтоenthusiasmLevelСвойство должно быть размещено после, иначе оно будет перезаписано свойством в старом состоянии.

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

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

Создать контейнер

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

ты сможешьСтатья Дэна АбрамоваPresentational and Container ComponentsУзнайте больше об этой концепции на

Сначала обновимsrc/components/Hello.tsxЭто изменит состояние.
мы будемPropsдобавить имяonIncrementа такжеonDecrementДва необязательных свойства обратного вызова:

export interface Props {
  name: string;
  enthusiasmLevel?: number;
  onIncrement?: () => void;
  onDecrement?: () => void;
}

Затем мы привязываем эти обратные вызовы к двум новым кнопкам, добавленным в компонент.

function Hello({ name, enthusiasmLevel = 1, onIncrement, onDecrement }: Props) {
  if (enthusiasmLevel <= 0) {
    throw new Error('You could be a little more enthusiastic. :D');
  }

  return (
    <div className="hello">
      <div className="greeting">
        Hello {name + getExclamationMarks(enthusiasmLevel)}
      </div>
      <div>
        <button onClick={onDecrement}>-</button>
        <button onClick={onIncrement}>+</button>
      </div>
    </div>
  );
}

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

Попробуйте прикрепить несколько тестов к вашему компоненту.

Теперь, когда наш компонент обновлен, мы готовы поместить его в контейнер.
Давайте создадимsrc/containers/Hello.tsxфайл и начните использовать следующие операции импорта.

import Hello from '../components/Hello';
import * as actions from '../actions/';
import { StoreState } from '../types/index';
import { connect, Dispatch } from 'react-redux';

Реальные две ключевые части здесь - это оригиналHelloкомпоненты и из react-reduxconnectфункция.
connectсможет фактически использовать наш оригинальныйHelloкомпонент и превратить его в контейнер с помощью двух функций:

  • mapStateToPropsЧасть текущего хранилища будет удалена, а данные, необходимые текущему компоненту, будут переданы.
  • mapDispatchToPropsон использует данныйdispatchФункции запускают действия в нашем магазине, создавая реквизиты обратного вызова.

Если мы помним, наше состояние приложения состоит из двух свойств:languageNameа такжеenthusiasmLevel.

С другой стороны, нашаHelloОжидается, что компоненты будут иметьname and an enthusiasmLevel.
mapStateToPropsСоответствующие данные будут получены из хранилища, а реквизиты компонента будут скорректированы по мере необходимости.
Продолжаем писать.

export function mapStateToProps({ enthusiasmLevel, languageName }: StoreState) {
  return {
    enthusiasmLevel,
    name: languageName,
  }
}

осторожность,mapStateToPropsсоздать только одинHello2 из 4 свойств, ожидаемых компонентом.

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

export function mapDispatchToProps(dispatch: Dispatch<actions.EnthusiasmAction>) {
  return {
    onIncrement: () => dispatch(actions.incrementEnthusiasm()),
    onDecrement: () => dispatch(actions.decrementEnthusiasm()),
  }
}

Наконец, мы готовы позвонитьconnect.

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

export default connect(mapStateToProps, mapDispatchToProps)(Hello);

Когда мы закончим, наш файл будет выглядеть так:

// src/containers/Hello.tsx

import Hello from '../components/Hello';
import * as actions from '../actions/';
import { StoreState } from '../types/index';
import { connect, Dispatch } from 'react-redux';

export function mapStateToProps({ enthusiasmLevel, languageName }: StoreState) {
  return {
    enthusiasmLevel,
    name: languageName,
  }
}

export function mapDispatchToProps(dispatch: Dispatch<actions.EnthusiasmAction>) {
  return {
    onIncrement: () => dispatch(actions.incrementEnthusiasm()),
    onDecrement: () => dispatch(actions.decrementEnthusiasm()),
  }
}

export default connect(mapStateToProps, mapDispatchToProps)(Hello);

создать магазин

давай вернемсяsrc/index.tsxсодержание.
Чтобы собрать все это вместе, нам нужно создать начальное состояние хранилища и настроить его со всеми редьюсерами.

import { createStore } from 'redux';
import { enthusiasm } from './reducers/index';
import { StoreState } from './types/index';

const store = createStore<StoreState>(enthusiasm, {
  enthusiasmLevel: 1,
  languageName: 'TypeScript',
});

storeДа... как вы могли догадаться, это центральное хранилище глобального состояния нашего приложения.

Далее мы заменим тот, который мы используем./src/components/Helloпройти через./src/containers/Helloи используйте реакцию-редуксProviderЧерез наш контейнер, чтобы подключить наш реквизит.
Мы импортируем каждую необходимую часть:

import Hello from './containers/Hello';
import { Provider } from 'react-redux';

и поставить нашstoreПерейти кProviderсвойства

ReactDOM.render(
  <Provider store={store}>
    <Hello />
  </Provider>,
  document.getElementById('root') as HTMLElement
);

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

Ejecting

Если в какой-либо момент вы почувствуете, что некоторые из факторов создания-реакции-приложения затрудняют настройку, вы всегда можете выбрать «Извлечь» и получить различные параметры конфигурации, которые вам нужны.
Например, если вы хотите добавить подключаемый модуль Webpack, вы можете воспользоваться функцией «извлечения», предоставляемой create-react-app.

простой бег

npm run eject

Ладиться!

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

Следующий шаг

create-реагировать-приложение имеет много вкусностей.

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

Если вы хотите узнать больше о Redux, вы можетеПроверьте официальный сайтПолучить документацию.
for MobXТо же самое.

Если вы хотите выполнить извлечение в какой-то момент, вам может понадобиться больше узнать о Webpack.
Вы можете посмотреть наши здесь.Прохождение React и Webpack здесь.

В какой-то момент вам может понадобиться маршрутизация.
Здесь есть несколько решений, ноreact-routerНаиболее популярен для проектов Redux и часто используется сreact-router-reduxС использованием.

translator

@author: Riu.Zen

@lastUpdateTime: 2017-10-01

Дополнительные инструкции

2017-10-19
Публикация Youdaoyun Notes была приостановлена, поэтому я напрямую переместил исходный текст, надеясь помочь всем.