Реализация и настройка для начала работы с redux, действиями, редукторами и регистратором внутри любых raction.js или реактивно-активный приложение.
Содержание
Магазин и провайдер Почему действия создатели? Состав Действия и редукторы в 14 шагах Redux-logger. Заключение
Магазин и провайдер
Вы можете либо следовать за этим постом Или Непосредственно проверить окончательное приложение из моего Github Repo здесь Отказ
Давайте начнем с установки пакетов.
NPM Установка –save redux red-redux redux-logger redux-thunk
Каждый компонент внутри нашего приложения будет иметь доступ к магазину, используя Hunt Helper от React-redux Библиотека, чтобы сделать это, вам придется выполнить эти шаги:
- Создайте экземпляр магазина Redux.
- Создайте тег поставщика из библиотеки React-Redux.
- Затем обратитесь к тому, что метка провайдера, проходящая в магазине в качестве опоры, то любой дочерний компонент к этому тему провайдера будет иметь доступ к этому магазину через контекстную систему внутри реакции.
- Создайте магазин (
index.js
) в отдельной папке.
// store/index.js import { createStore, compose, applyMiddleware } from 'redux'; import thunk from 'redux-thunk'; const store = createStore({ reducers, {}, // default state of the application compose( applyMiddleware(thunk) ) }) export default store;
- Создание по умолчанию или фиктивному редуктору, создавая новые редукторы папок/
- Создать
index.js
и добавьте пустышку для начала.
import { combineReducers } from 'redux'; export default combineReducers({ temp: () => {return {}} })
Редуктор должен вернуть объект или строку или номер и никогда не возвращаться undefined.
import reducers from '../Reducers';
- Импортировать магазин в
src/app.js.
// In src/App.js import { Provider } from 'react-redux'; import store from './Store'; import CustomTextInput from './Components/CustomTextInput';
Почему действия создатели?
Мы хотим минимизировать обязанности кого-либо из наших компонентов. Мы хотим сделать компонент максимально простым и максимально глупым, поэтому все наш соперник собирается сделать, это показать интернет-интерфейс. Всякий раз, когда наш компонент собирается сделать некоторую логическую работу, мы бы назвали создателем действий.
User types something -> call action creator with new text -> action creator returns an action -> action sent to all reducers -> reducers calculates new app state -> state sent to all components -> component rerender with new state -> wait for new change -> repeat.
Состав
Существуют разные способы структурирования вашего приложения.
Как правило, для небольших приложений
- index.ios.js - index.android.js - Tests/ - src/ - App.js # Entry point - Components/ - CustomTextInput.js - Actions/ - CustomTextInputActions.js - index.js - types.js - Reducers/ - index.js - Store/ - index.js - Navigation - Constants/ - Screens/ - Assets/ - Services/
Редукс контейнер дизайн шаблон
- index.ios.js - index.android.js - Tests/ - App/ - Components/ - Config/ - Containers/ - I18n/ - Reducers/ - index.js - Store/ - index.js - Navigation - Themes/ - Assets/ - Services/
Посмотрите на эти ссылки:
- https://github.com/infinitered/ChainReactApp/tree/master/App
- https://medium.com/@manggit/code-example-react-native-redux-realm-js-r3-js-cb35e8998a42
- https://medium.com/@dan_abramov/smart-and-dumb-components-7ca2f9a7c7d0
Положить тесты в той же папке.
Проще написать и модифицировать тесты, когда приложение идет большим.
- Составные части/
- Customdextinput.js.
- Customdextinput.test.js.
Действия и редукторы в 14 шагах
Допустим, мы хотим обновить текст в TextInput через действия и редукторы, так как будет выглядеть весь процесс?
Наша цель.
Шаг 1
Создайте обработчик событий Onchangetext и приложите обратный вызов this.onfextChanged и определить эту функцию в одном классе.
export default class CustomTextInput extends Component { onTextChange = (text) => { // Step-12 } render() { return (); } } this.onTextChange(text)} placeholder="Search" style={{ height: 80, width: 200, fontSize: 30 }} />
Использование вышеупомянутого синтаксиса запятнает нас к типу this.ontextChange.bind (это)
Другими словами, он знает, какой это
мы говорим о.
Шаг 2
Создать новую папку Действия
Шаг 3
Создайте новый файл внутри папки Действия Действия/index.js.
Шаг-4
Создать файл Действия/Виды.js. В папке действий и в этом файле мы создаем переменные для хранения типов действий.
Один файл для всех типов действий.
export const TEXT_CHANGED = 'text_changed';
Шаг-5
Создайте новый файл действий для обработки ваших пользовательских компонентов TextInput Действия/customdextinputice.js.
import { TEXT_CHANGED } from './types'; export const textChanged = (text) => { return { type: TEXT_CHANGED, payload: text }; }
Шаг 6.
Импортные действия в index.js.
export * from './CustomTextInputActions';
Шаг-7.
Создатель импорта действий в файле, который имеет наш текстовый компонент и импортировать соединять отсюда React-redux.
import { connect } from 'react-redux'; import textChanged from '../Actions'; class CustomTextInput extends Component { ... bla bla bla } export default connect(null, textChanged)(CustomTextInput);
Где мы сейчас сейчас?
user types something -> calls event handler -> calls action creator with new text -> action creator returns an action -> sends that actions to all the reducers
Мы еще не создали редукторов, и нам нужно один, чтобы поймать это действие и действительно сделать что-то об этом, поэтому давайте перейдем к следующему шагу.
Шаг-8.
Создать новую папку Редукторы
Шаг 9.
Создайте новый файл внутри папки редукторов Textreducer.js. справиться с этим действием.
const INITIAL_STATE = { text: '' }; export default ( state=INITIAL_STATE , action ) => { /* We always have the exact same format for every reducer we write, we always have a switch statement and depending on the action it will decide what to do with it. we can never return undefined from a reducer, every time our reducers are call we should have a default state. */ switch (action.type) { case: // in step 11 default: // Return the initial state when no action types match. return state } }
Шаг-10.
Создайте новый файл внутри папки редукторов index.js.
import { combineReducers } from 'redux'; import TextReducer from './TextReducer'; export default combineReducers({ // the keys here are going to be the property of state that we are producing. text_reducer: TextReducer });
Теперь, когда мы создали создатель редуктора и действия, нам нужно убедиться, что наши следы редуктора для действия соответствующего типа.
Шаг-11.
Импортируйте этот тип действия в наш редуктор. Textreducer.js. и добавить корпус для него.
import { TEXT_CHANGED } from '../Actions/types'; /* Remember that TEXT_CHANGED should be defined and must have a value otherwise it will be undefined and no error would popup and in the reducer we will have a case of undefined case undefined: return ... which is not what we want. */ const INITIAL_STATE = { text: '' }; export default ( state=INITIAL_STATE , action ) => { switch (action.type) { case TEXT_CHANGED: /* slice of state (that the reducer last published) + action | into the reducer | returns a new slice of state After our reducer runs, redux looks at the old value of the state and the new one. `is newState === oldState?` (matches the object) we must return a new object. (have to take care of immutable objects) Make a new object, take all the properties from the existing state object and throw that into our new object then define the property `text`, give it a value of action.payload and put it one top of whatever properties we had on the old state object. Now, since old state object already has a text property so, it will be overwritten with a new value. */ return {...state, text: action.payload} default: /* We will just return the state. Return the initial state when nothing changes hence no re-rendering. */ return state } };
Шаг-12.
Обновите наш метод обратного вызова и вызовите Creator Action, чтобы он мог обновить состояние.
onTextChange = (text) => { this.props.textChanged(text) }
Шаг-13.
Определите функцию MapStateToPOPS в файлосодержащем классе компонентов.
Это будет называться без глобального состояния приложений, и мы должны вернуть только имущество, которое мы заботимся о состоянии этого государственного объекта.
const mapStateToProps = state => { return { text: state.text_reducer.text } } // Pass it as the first argument to our connect function. export default connect(mapStateToProps, textChanged)(CustomTextInput);
Шаг-14.
Пройти значение в компонент
value={this.props.text}
Теперь каждый раз, когда вы обновляете текст в TextInput, он вызывает действие ответственна за обновление состояния и, следовательно, текст в текстовом режиме.
Redux-logger.
Чтобы проверить действия, вызванные в среде разработки, я использую Redux-logger.
import { createStore, compose, applyMiddleware } from 'redux'; import thunk from 'redux-thunk'; import { createLogger } from 'redux-logger'; import reducers from '../Reducers'; const middleWare = []; middleWare.push(thunk) const loggerMiddleware = createLogger({ predicate: () => process.env.NODE_ENV === 'development', }); middleWare.push(loggerMiddleware) const store = createStore( reducers, {}, compose( applyMiddleware(...middleWare) ) ); export default store;
Примечание. Этот пример является только для обеспечения лучшего понимания, я бы не рекомендовал использовать этот подход для такой простой задачи.
Заключение
Спасибо за чтение этого поста – надеюсь, вы нашли это полезным. Вы можете найти меня на Github , LinkedIn и Кодаментар Отказ Если у вас есть какие-либо вопросы, не стесняйтесь добраться до меня! Другие сообщения:
- Настройка вашего навигационного ящика в KIVY & KIVYMD
- Plyer: Platform Независимый слой совместимости
- Управление текстурой в Киве с использованием атласа
- Учебное пособие на новичком Киве: базовый курс сбоя для приложений в Киве
- Redux, Store, Действия, Редукторы и регистратор: Начните и немного дальше (1)
- Redux, Reactotron, действия, редукторы и саги (2)