Автор оригинала: FreeCodeCamp Community Member.
Panagiotis VRS.
Некоторые дни назад я хотел начать реализовать то, что я имел в виду последние 4 месяца: мигрируя проект Angularjs, чтобы реагировать с управлением состояния Redux.
Я сделал некоторые исследования по теме. И хотя там были некоторые статьи вокруг угловой миграции, я потерялся. Также я не смог найти, как вы можете сделать Redux через проект только для реагирования.
Существуют сотни проектов, которые придется решить в следующие годы переехать в другие основы, как Angularjs, и его библиотеки будут иметь меньшее и менее поддержку со стороны сообщества.
Я думал, что это может быть проще, поэтому я сделал это и сохранил несколько заметок, чтобы я мог поделиться своими выводами.
Начиная с Angularjs миграция для реагирования не является легкой задачей. И что произойдет, если вы хотите начать использовать Redux для управления государством? Ну, это не должно быть кошмаром!
Мой проект уже был переключен на ES6 с WebPack, так что это было одно, которое много помогло. Поэтому я предлагаю, прежде чем сделать такую миграцию, начать использование учебных и модульных зависимостей как можно скорее.
Мои потребности
Я хотел начать перемещать этот проект от Angularjs, чтобы реагировать, чтобы начать использовать все новые функции Современные веб-сайты, чтобы предложить относительно скорости, разделение кода в меньшие компоненты и, конечно, тестирование.
Я не собираюсь лгать – я не был достаточно тестировал или совсем вообще в этом проекте. За два месяца до этой миграции я начал реализовать некоторые тестирование принципов по проекту, чтобы я мог держать в пути в некоторых задачах. Суть – это было удивительно сложно настроить тестирование и покрытие, а в конце концов, потребовалось некоторое время для запуска задач.
Начать формировать это
Первое, что я сделал, было установить все необходимые зависимости, такие как React, React-DOM и React-redux. Вы также можете видеть версии, которые я использую ниже.
Самый крутой плагин всех был реагирован реагирован, который я использовал для перевода всех компонентов реагирования в угловые компоненты.
Затем для разработки нам необходимо установить зависимости Babel, чтобы иметь все крутые функции ES6. Имейте в виду, что у меня уже была Бабел, и я только вставлял это, чтобы увидеть версий и продолжать выровнять.
{ "dependencies": { "ng-redux": "^3.4.0-beta.1", "prop-types": "^15.5.10", "react": "^15.5.4", "react-dom": "^15.5.4", "react-redux": "^5.0.5", "react2angular": "^1.1.3", "redux": "^3.6.0", "redux-devtools": "^3.4.0", "redux-thunk": "^2.2.0", }, "devDependencies": { "babel-core": "^6.24.1", "babel-loader": "^6.4.1", "babel-preset-es2015": "^6.24.1", "babel-preset-react": "^6.24.1", "babel-preset-stage-2": "^6.24.1", "webpack": "^2.2.0", "webpack-dev-server": "^2.2.0", } }
Все сделано? Хороший!
Структура проекта
Это то, что я хотел сделать иметь эту структуру для всего проекта. Я видел это в полном проекте Mern на Github, потому что я использовал его в небольшом проекте, чтобы увидеть, как это получится очень простым и эффективным. Разделение для каждой страницы (контейнерной компоненты) и каждой страницы, чтобы иметь их компоненты. Вы также можете иметь папку внешнего имени компонентов, чтобы держать все глобальные компоненты там. Обратитесь здесь, если примеры кода не имеют смысла;)
Также вы можете увидеть, как проект Mern обрабатывает рендеринг бокового сервера, когда выполняется миграция (другая отличная функция, которую вы можете использовать из React!) Для того, чтобы сделать его сделать.
У меня нет файлов ETC Index в этой структуре, просто фокусируясь на компонентах реагирования.
├── app - holds all the components │ ├── common - is not a module of the app. This holds utils for the react app. │ │ └── utils │ ├── ratings │ │ ├── components │ │ │ ├── RatingItem │ │ │ │ ├── RatingItem.js │ │ │ │ └── RatingItem.less │ │ │ ├── RatingList │ │ │ │ ├── RatingList.js │ │ │ │ └── RatingList.less │ │ │ ├── RatingsPage.js │ │ │ ├── RatingsReducer.js │ │ │ └── RatingsActions.js ├── config - all config files for development and production └── locales - locale files
Создайте свой первый компонент
Делать ваш первый компонент относительно прост. Я ожидаю, что вы уже знакомы с реагированием, поэтому я просто буду прыгнуть в код. Вы можете разделить свой код как можно больше компонентов, которые вы, кажется, соответствуют вашим потребностям. Пример компонента похож на ниже. Вот как я регулярно переключил небольшие (презентационные) компоненты, возможно, ул с данными или каждым элементом ул.
import React from "react"; import PropTypes from "prop-types"; function RatingsItem(props) { return ({props.rating.text}); } RatingsItem.propTypes = { rating: PropTypes.shape({ id: PropTypes.string.isRequired, text: PropTypes.bool.isRequired, reported: PropTypes.bool.isRequired, }), }; export default RatingsItem;
Эти небольшие компоненты теперь могут быть импортированы в наш проект. Когда вы определяете свой модуль в приложении Angularjs, вы можете импортировать компонент, и с помощью Reaction21ual Tency Singence измените его на директив/компонент Angularjs.
.component("ratingsItem", react2angular(RatingsItem))
Теперь на .html, если вы используете
Надеюсь, вы не потерялись. Ты со мной? … хорошо. Помнить!
Следующим шагом является то, что вы хотите изменить весь модуль для реагирования. Это будет компонент контейнера в нашем приложении React. Я разделил их на страницы. Прежде чем мы перейдем к этому, хотя нам нужно начать использовать действия Redux и редукторы. Это поможет нам на следующем шаге, когда мы будем комбинировать редукторы с Redux!
Таким образом, для реализации некоторого Redux для наших компонентов контейнеров сначала вам нужно будет определить ваш редуктор и действие для этого компонента рейтинга. Вы можете увидеть Структура приложений выше, чтобы увидеть название и положение тех, кто в моем проекте.
Мы не будем объяснять действия и редукторы в этой теме, когда я делаю тот факт, что вы уже знакомы с действиями redux и редукторами
Мой редуктор выглядит так.
import { ADD_RATINGS } from "./RatingsActions"; const initialState = { list: [] }; const RatingsReducer = (state = initialState, action) => { switch (action.type) { case ADD_RATINGS : return { ...state, list: action.ratings, }; default: return state; } }; /* Selectors */ // Get all ratings export const getRatings = state => state.Ratings.list; // Export Reducer export default RatingsReducer;
Действия выглядят так.
import callApi from "../common/utils/apiCaller"; export const ADD_RATINGS = "ADD_RATINGS"; export function addRatings(ratings) { return { type: ADD_RATINGS, ratings, }; } export function fetchRatings() { return (dispatch) => { return callApi("ratings").then(ratings => { dispatch(addRatings(ratings)); }); }; }
Простой! Делать две вещи только ради тестирования, которые работают. Вы можете использовать свой собственный.
Так что это будет мои рейтинги. Вот как выглядит моя страница. Вы также можете пройти «Привет там» внутри DIV, чтобы вы могли быть уверены, что у вас есть что-то без данных. Снова только для тестирования.
import { connect } from "react-redux"; import React, { Component } from "react"; import PropTypes from "prop-types"; // Import Components import RatingList from "./components/RatingList/RatingList"; // Import Actions import { fetchRatings } from "./RatingsActions"; // import Reducer import { getRatings } from "./RatingsReducer"; class RatingsPage extends Component { debugger; render() { return (); } } // Retrieve data from store as props const mapStateToProps = (state) => { return { ratings: getRatings(state) } }; const mapDispatchToProps = (dispatch) => { return { dispatch, fetchRatings: dispatch(fetchRatings()), }; } RatingsPage.propTypes = { ratings: PropTypes.arrayOf(PropTypes.object), dispatch: PropTypes.func.isRequired, }; export default connect(mapStateToProps, mapDispatchToProps)(RatingsPage);
Теперь нам нужно будет использовать ng-redux, чтобы создать магазин и пройти, который хранится до наших компонентов. Что нам нужно сделать, это объединить все наши редукторы приложений, как мы в реакции, поэтому я создал отдельный файл для этого, чтобы использовать это в будущем, когда я удалю Angularjs. Я называю этими «редукторами», и это выглядит так.
То, что он на самом деле делает, вы определяете здесь все ваши редукторы вашего приложения, чтобы объединить их, а на следующем шаге мы «кормием» эти редукторы в Redux для состояния. Вы увидите, что у меня есть только рейтинги только, но вы можете (и надо) заполнить любой новый компонент по пути здесь.
import {combineReducers} from "redux"; import Ratings from "./ratings/RatingsReducer"; // Combine all reducers into one root reducer export const RootReducer = combineReducers({ Ratings });
Теперь нам нужно импортировать Redux. В нашем главном файле, когда мы определяем все приложение, которое мы импортируем комбинированные уменьшения, Ngrredux, Redux Thunk и передайте его в качестве зависимости модуля.
import ngRedux from "ng-redux"; import thunk from "redux-thunk"; import {RootReducer} from "./Reducers"; angular .module( "funkmartini", [ ..., ngRedux, ..... ] ) .config(configApp) .run(runApp);
В вашей конфигурации приложения я передаю $ NGREDUXPROVIDER, и я создаю свой магазин. Я также передаю Redux devtools, если вы хотите поставить его в свой проект, если не просто удалить из функции CreatestoreWith.
$ngReduxProvider.createStoreWith(RootReducer, [thunk], [$window.__REDUX_DEVTOOLS_EXTENSION__()]);
Вы все настроители сейчас. Используя $ NGREDUX в своих контроллерах, вы теперь можете получить магазин вашего приложения!
Суммировать до сих пор
Таким образом, мы сделали небольшой компонент. Затем мы изменили весь модуль углового модуля и создали компонент контейнера для его замены. Теперь мы хотели пройти некоторые данные и использовать Redux и вот почему мы создали магазин redux, чтобы иметь начальное состояние, а использование или редукторы определяют в файле, чтобы обновить его.
Передайте этот магазин к компонентам!
Потому что я использовал $ StudeProvider в угловом угловании, и у меня было что-то вроде ниже. То, что я сделал, перестанет использовать импорт шаблона HTML-страницы, и я использовал непосредственно страницу реагирования, которую я определил как компонент до того, как в Angularjs, как мы ранее. Так что я взял это.
function ratingsConfig($stateProvider) { $stateProvider .state("ratings", { url: "/ratings", views: { "main@settings": { templateUrl: ratingsTemplate, controller: "RatingsController" } } }); }
и изменить это к этому.
function ratingsConfig($stateProvider) { $stateProvider .state("ratings", { url: "/ratings", views: { "main@settings": { template: ``, controller: "RatingsController" } } }); }
Как вы можете видеть, я передаю переменную магазина в реквизитах RatingsPage. Вы представляете это правильно, я использую только RatingsController, чтобы получить и пройти этот магазин. Так что контроллер должен выглядеть так
function ratingsController($scope, $ngRedux) { $scope.store = $ngRedux; }
Таким образом, redux может определить, что хранилище в реквизитах на самом деле это магазин, который нуждается в функции Connect ().
Заключение
Миграция Angularjs для реагирования/redux сложно и может занять время, но не должно быть кошмаром. После того, как вы сделали с какой-то базовой конфигурацией вокруг проекта, его можно легко расширить и медленно стать реагированным проектом. При необходимости работать как можно ближе к простому JavaScript, действительно отлично. Хотя это может занять некоторое время миграция, я думаю, что в долгосрочной перспективе его стоит. Предложения, которые я пропустил в этой статье, состоит в том, что вы можете начать использовать некоторые льготы по пути (Jslint, Eslint – Airbnb) и не забудьте проверить новые компоненты!
Веселитесь и дайте мне знать, как это происходит!
Ресурсы
Наше путешествие мигрирует 100К строки кода из Angularjs, чтобы реагировать (глава 1) Настоящая последующая сумма нашей стратегии, моделей и уроков извлечена из миграции из Angularjs для реагирования/redux. Tech.small-improvements.com.
Миграция на redux · redux Создайте функцию «CreateFluxStore» (Редуктор), которая создает магазин Flux, совместимый с вашим существующим приложением из … redux.js.org.
Hashnode/Merner-Starter Meern-Starter – Boilerplate для начала работы с Mern Mern Stack github.com.