предисловие
Если вы хотите увидеть теоретическую детскую обувь, нажмите здесьредукционная китайская документацияилиредукс официальная документация, в этой статье не будут слишком уж преднамеренно вводить крупномасштабные теории, в этой статье не проводится сравнение фреймворков, только для тех, кто хочет научитьсяredux
Детская обувь предоставляет содержательные, эффективные и простые для понимания справочные ресурсы для обучения, чтобы поделиться тем, что вы приобрели в процессе обучения. Статья будет длиннее после обновления, пожалуйста, наберитесь терпения, чтобы прочитать и понять, и внимательно попробовать. незнакомыйredux
Не беда, вы можете следовать идеям статьи и совместить триdemo
После стука, я считаю, вы получите много пользы. (В конце текста пасхалки).
Обновленный контент
-
redux
Базовое использование (с демонстрацией) -
redux
Middleware
Использование (с демонстрацией) -
redux
интегрированныйnavigation
(с демо)
react native
Версия.
подражать официальномуasyncдемоreact native
Версия.
интегрированныйreact-native-navigation
поставить первые дваdomo
всесторонний.
Быть обновленным
- продолжение следует......
Почему я хочу написать это демо
К некоторым детской обуви могут возникнуть вопросы
Q: Официальный неTodos
демо? Зачем писать это демо?
О: Все официальные демоверсииreact
, скорее, чемreact native
из. Я также нашел много о введенииredux
, но я обнаружил, что информация, которую я нашел, была либо слишком простой, либо введение не было исчерпывающим, предоставленная демонстрационная загрузка была непригодной для использования и т. д., что заставило меня испытать желание построить колесо самостоятельно, и этоdemo
не только оredux
Основа-то, но через три комплектаdemo
Практикуйте связную графику и текст, чтобы читатели могли лучше понять, и будут обновлены в будущем.redux
В процессе, я надеюсь, все будут поощрять и поддерживать.
Спецификация кода, принятая демо
Обычно большой проект требует участия многих разработчиков на более позднем этапе.Если каждый разработчик использует свой собственный набор спецификаций кода, последствия этого таковы: последующая работа по управлению кодом принесет много проблем и потерь. времени на рефакторинг, а также новичкам потребуется больше времени, чтобы понять код при чтении кода, и других легко завести в канаву, поэтому крупномасштабный проект должен соблюдать некоторые спецификации при изначальном построении архитектуры.
Итак, как мы можем набирать чистый и элегантный код? Как мы можем проверить качество нашего кода?
Я настоятельно рекомендую соблюдать здесьairbnb/javascriptСпецификация и использованиеeslintдля проверки качества кода вашего собственного кода (соответствует ли он спецификации), так как они были одобрены многими компаниями и разработчиками. (Здесь слишком много предисловияairbnb
eslint
, в этой статье только идеи, хочу узнать больше и поискать самостоятельно)
Прежде чем использовать спецификацию кода, мы, возможно, много лет писали код в своем стиле, и вдруг может быть очень неудобно адаптироваться к этой спецификации. это после долгого времени У кого нет процесса Процесс болезненный, но после боли он принесет вам качественную сублимацию, и вы сможете потихоньку его осмыслить и пережить на себе. Хорошие вещи будут приняты миром, а плохие со временем будут заменены, поэтому, как квалифицированный программист (особенно фронтенд-программист), вы должны принять изменения, потому что они сделают вас лучше, чтобы вас признали публикой, если вы не хотите сделать себя лучше.
Что может сделать для нас редукс
Две диаграммы показывают:
редукс-функции
-
Единый источник достоверной информации: для всего приложенияstateхранится в дереве объектов, и это дерево объектов существует только в одномstore середина.
-
Состояние доступно только для чтения: единственный способ изменить состояние — запуститьaction, действие — это обычный объект, используемый для описания произошедшего события.
-
Используйте чистые функции для выполнения модификаций: чтобы описать, как действия изменяют дерево состояний, вам нужно написатьreducers.
-
Предсказуемость: все действия пользователей определяются вами заранее.
-
Единое управление состоянием: все состояния распределяются и управляются в хранилище.
Какие разработчики и проекты подходят для редукса
здесь только дляreact native
Для развития:
-
Новичок: только начало
react native
Я не рекомендую его использовать, потому что вы еще не знаете, как его использовать, рекомендуется сначала достичь среднего уровня. -
Промежуточный: использовать
react native
сделать более одного уже перечисленного不复杂
Приложенияredux
, либо не используется, так как его использование не позволяет быстро итеративно разрабатывать на ранней стадии, и использовать его в таком проектеredux
подобно大炮打蚊子
, побочные эффекты велики. Но вы можете сначала понять его и открыть для себя его преимущества. Это своего рода относительно простое приложение: когда пользователь инициирует действие (программе нужноsetState({xxx:xxx})
), когда поток состояния приложения выглядит следующим образом: -
Дополнительно: использовать
react native
сделать более одного уже перечисленного复杂
приложений (с обменом мгновенными сообщениями, сложной компоновкой интерфейса, слишком большим количеством уровней вложенности компонентов и т. д.) и такими сложными приложениями: когда пользователь инициирует действие (программа требуетsetState({xxx:xxx})
), когда поток состояния приложения выглядит следующим образом:
Последствия этого состояния анализируются в двух аспектах:
- Производительность: избыточная передача состояния между родительским и дочерним компонентами приводит к трате драгоценных ресурсов памяти, и в то же время скорость рендеринга интерфейса будет ниже, а естественный пользовательский опыт будет хуже.
- Управление состоянием: когда программа продолжает повторяться, а макет интерфейса становится все более и более сложным, она неизбежно производит много
state
государство, как вы эффективно управляете этими состояниями? Что заставляет пользовательский интерфейс отображаться несколько раз? Какой шаг вызывает изменение компонентов пользовательского интерфейса? без использованияredux
Вы, возможно, обнаружили ранее, что можете использоватьshouldComponentUpdate
Чтобы уменьшить ненужный рендеринг в подкомпонентах, но ведь это не может решить сложную проблему управления состоянием. когда вы используетеredux
После этого сложный поток состояния приложения выглядит так:Прочитав вышеприведенные картинки и тексты, у вас появилось интуитивное понимание, какие проекты подходят для редукса?Спасибо@justjavacПоддержка анимации предоставлена статьей.
Redux для реагирования на собственную рабочую логическую диаграмму
благодарный@студия черный лесНаглядная логическая схема предоставлена автором
Анализ инженерной структуры Redux
Я внес некоторые изменения в официальную демо-часть локации, смотрите разбор кода:
Разделение труда
-
js/actions
Что делает содержимое этой папки: определяет поведение пользователя. -
js/reducers
Что делает содержимое этой папки: реагировать на поведение пользователя, возвращать измененное состояние и отправлять его вstore
. -
js/components
Что делает содержимое этой папки: пользовательские компоненты. -
js/containers
Что делает содержимое этой папки: поставитьcomponents
Компоненты в папке, связанные с изменением состояния, инкапсулируются во второй раз. -
App.js
Входной файл (хранилище находится здесь), почему я должен определять хранилище здесь? потому что он уникален и должен использоватьсяreact-redux
который предоставилProvider
Можно использовать другие компоненты компонента, обертывающего запись.redux
серединаstore
эффективный. -
global.js
Храните глобально определенные переменные, константы, методы и т. д.
На что обратить внимание
- в проекте
redux
изstore
уникален и не может использоваться в несколькихstore
. - Держать
reducer
Чистота очень важна. никогда вreducer
Выполните эти операции в:
- Изменить входящие параметры;
- Выполнение операций с побочными эффектами, таких как
API
Прыжок запроса и маршрутизации;- вызвать нечистую функцию, например
Date.now()
илиMath.random()
;
- Использование оператора распространения объекта
...
заменятьObject.assign()
является лучшим решением. - Первая буква имени компонента должна быть заглавной, т.е.
components
а такжеcontainers
Первая буква файлов в папке должна быть заглавной. - должно быть сведено к минимуму
action
Данные в (могут передавать отдельные данные, но не объект, могут передавать объект, но не массив)
//good
function todoApp(state = initialState, action) {
switch (action.type) {
case SET_VISIBILITY_FILTER:
return Object.assign({}, state, {
visibilityFilter: action.filter
})
default:
return state
}
}
//best
function todoApp(state = initialState, action) {
switch (action.type) {
case SET_VISIBILITY_FILTER:
return { ...state, visibilityFilter: action.filter }
default:
return state
}
}
Подробный код
js/actions/types.js
//添加列表数据
export const ADD_TODO = 'ADD_TODO';
//筛选
export const SET_VISIBILITY_FILTER = 'SET_VISIBILITY_FILTER';
//文字添加/取消中划线
export const TOGGLE_TODO = 'TOGGLE_TODO';
выпускать:
определение действия
Почему я ставлю пользовательскийaction
(поведения) определения извлекаются отдельно, чтобы написать одинtype.js
?
- Удобное управление статусами.
- возможность повторного использования.
js/actions/index.js
import {
ADD_TODO,
SET_VISIBILITY_FILTER,
TOGGLE_TODO,
} from './types'
let nextTodoId = 0;
export const addTodo = text => ({
type: ADD_TODO,
id: nextTodoId++,
text
});
export const setVisibilityFilter = (filter) => ({
type: SET_VISIBILITY_FILTER,
filter
});
export const toggleTodo = id => ({
type: TOGGLE_TODO,
id
});
выпускать:
Функция создания действия
Action
Чтобы создать функцию, нужно сгенерироватьaction
Методы. "action
" а также "action 创建函数
Эти два понятия легко смешиваются, и лучше всего различать их при употреблении.
существуетRedux
серединаaction
Создание функции просто возвращаетaction
:
js/reducers/todos.js
import {
ADD_TODO,
TOGGLE_TODO,
} from '../actions/types'
const todos = (state = [], action) => {
let {id, text, type} = action;
switch (type) {
case ADD_TODO:
return [
...state,
{
id: id,
text: text,
completed: false
}
];
case TOGGLE_TODO:
return state.map(todo => (todo.id === id) ? {...todo, completed: !todo.completed} : todo);
default:
return state;
}
};
export default todos;
js/reducers/visibilityFilter.js
import { SET_VISIBILITY_FILTER } from '../actions/types'
import { visibilityFilters } from '../global'
const { SHOW_ALL } = visibilityFilters;
const visibilityFilter = (state = SHOW_ALL, action) => {
let {type, filter} = action;
switch (type){
case SET_VISIBILITY_FILTER:
return filter;
default:
return state
}
};
export default visibilityFilter;
выпускать:
reducer
это чистая функция, которая принимает старыйstate
а такжеaction
, вернуть новыйstate
(Вышеуказанные два файла могут просматривать дваreducer
).
Уведомление:
Redux
При первом исполненииstate
дляundefined
, вам нужно установить начальныйstate
.- каждый
reducer
Отвечает только за управление глобальнымstate
часть отвечает. каждыйreducer
изstate
Параметры разные, соответствующие той части, которой он управляетstate
данные.
js/reducers/index.js
import { combineReducers } from 'redux'
import todos from './todos'
import visibilityFilter from './visibilityFilter'
export default combineReducers({
todos,
visibilityFilter
})
выпускать:
combineReducers()
Все, что он делает, это генерирует функцию, которая вызывает вашу сериюreducer
, каждыйreducer
фильтровать по их ключуstate
часть данных в, а затем эта сгенерированная функция принимает всеreducer
Результаты объединяются в один большой объект.
поверхностноcombineReducers()
Эффект заключается в объединении несколькихreducer
синтезированныйreducer
.
js/components/Todo.js
import React, { Component } from 'react'
import {
Text,
TouchableOpacity
} from 'react-native'
import PropTypes from 'prop-types'
export default class Todo extends Component {
static propTypes = {
onClick: PropTypes.func.isRequired,
completed: PropTypes.bool.isRequired,
text: PropTypes.string.isRequired
};
render(){
let { onClick, completed, text } = this.props;
return (
<TouchableOpacity
style={{
flexDirection: 'row',
flex: 1,
height: 50,
alignItems: 'center',
justifyContent: 'center',
backgroundColor: '#cccccc',
marginTop: 10
}}
onPress={onClick}>
<Text style={{ textDecorationLine: completed ? 'line-through' : 'none'}}>{text}</Text>
</TouchableOpacity>
);
}
}
js/components/TodoList.js
import React, { Component } from 'react'
import PropTypes from 'prop-types'
import {
FlatList
} from 'react-native'
import Todo from './Todo'
export default class TodoList extends Component {
static propTypes = {
todos: PropTypes.arrayOf(
PropTypes.shape({
id: PropTypes.number.isRequired,
completed: PropTypes.bool.isRequired,
text: PropTypes.string.isRequired
}).isRequired
).isRequired,
toggleTodo: PropTypes.func.isRequired
};
_renderItem = (data) => {
let dataItem = data.item;
let { id } = dataItem;
let { toggleTodo } = this.props;
return (
<Todo
{...dataItem}
onClick={() => toggleTodo(id)}
/>
)
};
render() {
let { todos } = this.props;
return (
<FlatList
data={todos}
keyExtractor={(item)=>item.id.toString()}
renderItem={this._renderItem}
/>
)
}
}
js/components/Link.js.js
import React, { Component } from 'react'
import PropTypes from 'prop-types'
import {
TouchableOpacity,
Text
} from 'react-native'
export default class Link extends Component {
static propTypes = {
active: PropTypes.bool.isRequired,
filter: PropTypes.string.isRequired,
onClick: PropTypes.func.isRequired
};
render() {
let { active, filter, onClick } = this.props;
return (
<TouchableOpacity
style={{
marginLeft: 4,
height: 40,
flex:1,
borderWidth: 1,
borderColor: '#ccc',
alignItems: 'center',
justifyContent:'center'
}}
onPress={onClick}
>
<Text style={{fontSize: 10, color: active ? 'black' : '#cccccc'}}>{filter}</Text>
</TouchableOpacity>
);
}
}
js/components/Filters.js
import React, { Component } from 'react'
import {
View,
} from 'react-native'
import FilterLink from '../containers/FilterLink'
import { visibilityFilters } from '../global'
const { SHOW_ALL, SHOW_COMPLETED, SHOW_ACTIVE } = visibilityFilters;
export default class Filters extends Component {
render(){
return(
<View style={{ flexDirection: 'row', marginTop: 20}}>
<FilterLink filter={SHOW_ALL} />
<FilterLink filter={SHOW_COMPLETED} />
<FilterLink filter={SHOW_ACTIVE} />
</View>
)
}
}
выпускать:
Вышеупомянутые четыре файла представляют собой четыре настраиваемых компонента отображения пользовательского интерфейса, эти компоненты определяют только внешний вид и не заботятся об источнике данных и способах изменения. Рендеринг всего, что передается. Если поставить код изRedux
При переходе на другие архитектуры эти компоненты можно использовать без каких-либо изменений. они не зависят отRedux
.
js/containers/AddTodo.js
import React, { Component } from 'react'
import {
View,
TextInput,
Button,
} from 'react-native'
import { connect } from 'react-redux'
import { addTodo } from '../actions'
class AddTodo extends Component {
constructor(props){
super(props);
this.inputValue = '';
}
render(){
let { dispatch } = this.props;
return (
<View style={{flexDirection: 'row'}}>
<TextInput
style={{flex:1, borderWidth: 1, borderColor: '#cccccc', textAlign: 'center'}}
onChangeText={text => this.inputValue = text}
/>
<Button title="Add Todo" onPress={() => dispatch(addTodo(this.inputValue))}/>
</View>
)
}
}
export default connect()(AddTodo)
js/containers/FilterLink.js
import { connect } from 'react-redux'
import { setVisibilityFilter } from '../actions'
import Link from '../components/Link'
const mapStateToProps = (state, ownProps) => ({
active: ownProps.filter === state.visibilityFilter,
filterText: ownProps.filter
});
const mapDispatchToProps = (dispatch, ownProps) => ({
onClick: () => dispatch(setVisibilityFilter(ownProps.filter))
});
export default connect(
mapStateToProps,
mapDispatchToProps,
)(Link)
js/containers/VisibleTodoList.js
import { connect } from 'react-redux'
import { toggleTodo } from '../actions'
import TodoList from '../components/TodoList'
import { visibilityFilters } from '../global'
const { SHOW_ALL, SHOW_COMPLETED, SHOW_ACTIVE } = visibilityFilters;
const getVisibleTodos = (todos, filter) => {
switch (filter) {
case SHOW_COMPLETED:
return todos.filter(t => t.completed);
case SHOW_ACTIVE:
return todos.filter(t => !t.completed);
case SHOW_ALL:
return todos;
default:
throw new Error('Unknown filter: ' + filter)
}
};
const mapStateToProps = state => ({
todos: getVisibleTodos(state.todos, state.visibilityFilter)
});
const mapDispatchToProps = dispatch => ({
toggleTodo: id => dispatch(toggleTodo(id))
});
export default connect(
mapStateToProps,
mapDispatchToProps,
)(TodoList)
выпускать:
Вышеупомянутые три являются компонентами-контейнерами, которые используются для подключения компонентов дисплея кRedux
.
Вкратце: просто запомните одно предложение: компоненты представления пользовательского интерфейса отвечают за представление пользовательского интерфейса, а компоненты-контейнеры отвечают за управление данными и логикой.Иногда трудно сказать, следует ли вам использовать компонент контейнера или компонент представления. Как этот небольшой компонент:
AddTodo.js
Содержит кнопку «Добавить» и поле ввода
Технически возможно разделить его на два компонента, но, во-первых, делать это немного рано. Можно смешивать контейнеры и презентации в нескольких очень маленьких компонентах. Когда бизнес становится сложным, становится очевидным, как его разделить. Так что пока используйте гибрид.
использовано вышеreact-redux
изconnect()
метод для связывания компонента представления с компонентом контейнера.Этот метод оптимизирован по производительности, чтобы избежать большого количества ненужного дублирования рендеринга. (Таким образом, вам не нужно вручную реализовывать его для повышения производительности.Реагировать на предложения по оптимизации производительности середина shouldComponentUpdate
метод. )
использоватьconnect()
Прежде необходимо определитьmapStateToProps
Эта функция указывает, как преобразовать текущийRedux store state
сопоставляется с компонентом презентацииprops
середина. Например,VisibleTodoList
нужно рассчитатьTodoList
серединаtodos
, поэтому определите в соответствии сstate.visibilityFilter
фильтроватьstate.todos
метод, а вmapStateToProps
используется в.
кроме чтенияstate
, компоненты контейнера также могут быть распределеныaction
. Аналогичным образом можно определитьmapDispatchToProps()
метод полученияdispatch()
метод и возвращает метод обратного вызова, который, как ожидается, будет внедрен в свойства компонента презентации. Например, мы хотимVisibleTodoList
К TodoList
Внедрить компонент под названиемonTodoClick
Реквизит, также надеемсяonTodoClick
может распространятьTOGGLE_TODO
этоaction
.
Наконец, используйтеconnect()
СоздайтеVisibleTodoList
и передать эти две функции.
js/components/Group.js
import React, { Component } from 'react'
import {
View
} from 'react-native'
import AddTodo from '../containers/AddTodo'
import Filters from '../components/Filters'
import VisibleTodoList from '../containers/VisibleTodoList'
export default class Group extends Component {
render() {
return (
<View style={{paddingHorizontal: 20, paddingVertical: 44}}>
<AddTodo/>
<Filters/>
<VisibleTodoList/>
</View>
);
}
}
выпускать:
Group.js
Он заключается в том, чтобы объединить все связанные компоненты, чтобы сформировать законченный интерфейс.
App.js
import React, { Component } from 'react'
import { createStore } from 'redux'
import { Provider } from 'react-redux'
import Group from './js/components/Group'
import rootReducer from './js/reducers'
export default class App extends Component {
render() {
const store = createStore(rootReducer);
return (
<Provider store={store}>
<Group />
</Provider>
);
}
}
выпускать:
Входной файл входящийStore
- Создайте
store
входящийreducers
. - использовать
Provider
упаковка компонентовGroup
компоненты,store
перешел в собственностьProvider
.
На этом анализ кода завершен. Это письмо заканчивается здесь. Я считаю, что если вы внимательно прочитаете его, вы в какой-то степени что-то приобретете.demo
Если вы плохо это понимаете, то следуйте идее анализа кода, чтобы набрать код еще несколько раз, и тогда вы поймете Я буду продолжать обновлять незаконченный контент, когда у меня будет время.
〰️〰️〰️〰️〰️〰️〰️〰️〰️〰️〰️〰️〰️〰️〰️〰️〰️〰️〰️〰️〰️〰️〰️〰️〰️〰️
⭐️⭐️⭐️⭐️⭐️⭐️⭐️⭐️⭐️⭐️ Великолепная разделительная линия ⭐️⭐️⭐️⭐️⭐️⭐️⭐️⭐️⭐️⭐️⭐️
〰️〰️〰️〰️〰️〰️〰️〰️〰️〰️〰️〰️〰️〰️〰️〰️〰️〰️〰️〰️〰️〰️〰️〰️〰️〰️
Прошло несколько дней с момента последнего обновления, и сегодняшнее обновление:Middleware
(промежуточное ПО).
Роль ПО промежуточного слоя
Middleware
вActions
а такжеDispatcher
Встроенные между ними инструменты существуют для решения определенных задач и повышения эффективности нашей разработки.
Вот три часто используемых промежуточного программного обеспечения:
- redux-thunkПромежуточное ПО: требуется для асинхронных операций в проекте (например: запрос данных сервера, локального хранилища и т. д.).
-
redux-actionsПромежуточное ПО: помогает обрабатывать и создавать действия
actions
(Эта статья не представляет его, и его можно использовать для создания последующих проектов после сложных проектов). -
redux-loggerПромежуточное ПО: используется для печати
action
журнал. включиreact native
В режиме удаленной отладки вы можете увидеть изменение состояния печати на консоли, запустив демонстрацию.
Схематическая диаграмма после добавления промежуточного ПО выглядит следующим образом:
Подробный основной код
этот разdemo
Чтобы сократить объем статьи, код будет только объяснен.Middleware
часть, так сказатьdemo
в серединеreducers
,components
,containers
Новые добавленные файлы не будут слишком подробно объясняться.Если вы не понимаете, вы можете вернуться и снова проанализировать содержимое первого обновления.
actions/types.js
Добавьте следующий код
//请求帖子列表
export const REQUEST_POSTS = 'REQUEST_POSTS';
//帖子返回数据
export const RECEIVE_POSTS = 'RECEIVE_POSTS';
//切换数据源
export const SELECT_SUBREDDIT = 'SELECT_SUBREDDIT';
//使缓存过期失效
export const INVALIDATE_SUBREDDIT = 'INVALIDATE_SUBREDDIT';
actions/index.js
Добавьте следующий код
export const selectSubreddit = subreddit => ({
type: SELECT_SUBREDDIT,
subreddit
});
export const invalidateSubreddit = subreddit => ({
type: INVALIDATE_SUBREDDIT,
subreddit
});
export const requestPosts = subreddit => ({
type: REQUEST_POSTS,
subreddit
});
export const receivePosts = (subreddit, json) => ({
type: RECEIVE_POSTS,
subreddit,
posts: json.data,
receivedAt: Date.now()
});
const fetchPosts = subreddit => dispatch => {
// API 发起请求
dispatch(requestPosts(subreddit));
return fetch(`http://localhost:8081/data/${subreddit}.json`)
.then(response => response.json())
.then(json => {
setTimeout(()=>{
//使用 API 请求结果来更新应用的 state
dispatch(receivePosts(subreddit, json))
},2000);
})
};
const shouldFetchPosts = (state, subreddit) => {
const posts = state.postsBySubreddit[subreddit];
if (!posts) {
return true
}
if (posts.isFetching) {
return false
}
return posts.didInvalidate
};
export const fetchPostsIfNeeded = subreddit => (dispatch, getState) => {
if (shouldFetchPosts(getState(), subreddit)) {
return dispatch(fetchPosts(subreddit))
}
};
выпускать
Главное, на что следует обратить внимание выше, это то, что
fetchPosts
возвращает функцию, а обычныйAction 创建函数
Возвращает объект по умолчанию.- Параметры возвращаемой функции:
dispatch
а такжеgetState
эти двоеRedux
метод, обычныйAction 创建函数
ПараметрыAction
Содержание.- В возвращаемой функции сначала введите
Action
: dispatch(requestPosts(subreddit)), указывая на то, что операция начинается.- После завершения асинхронной операции выполните еще одну
Action
: receivePosts(subreddit, json), означающий окончание операции.
Объяснение источника данных в демо:
Я собирался использовать официальныйreddit demoAPI, и, наконец, нашел официальный данный
demo
Данные запроса сообщат об ошибке, поэтому локальные данные json используются для имитации процесса загрузки данных из сетевого API с задержкой в две секунды.
App.js
import React, { Component } from 'react'
import { applyMiddleware, createStore } from 'redux'
import { createLogger } from 'redux-logger'
import { Provider } from 'react-redux'
import thunk from 'redux-thunk'
import LoadPosts from './js/containers/LoadPosts'
import rootReducer from './js/reducers'
export default class App extends Component {
render() {
const logger = createLogger();
const store = createStore(
rootReducer,
applyMiddleware(thunk, logger)
);
return (
<Provider store={store}>
<LoadPosts/>
</Provider>
);
}
}
выпускать
по сравнению с предыдущимdemo
изApp.js
,существуетcreateStore
При изменении параметров появляется еще одинapplyMiddleware(thunk, logger)
Параметры промежуточного ПО.
Нетрудно увидеть детскую обувь, которая понимает содержание первого обновления,Action
Кstore.dispatch
метод отправлен. а такжеstore.dispatch
В обычных условиях параметры могут быть только объектами, а не функциями.
Чтобы решить эту проблему, нам нужно использовать промежуточное ПО.redux-thunk
Модернизацияstore.dispatch
,Сделатьstore.dispatch
Может принимать функции в качестве параметров.
Уведомление
Некоторое промежуточное программное обеспечение имеет требования к порядку, проверьте документацию перед использованием. Например, логгер должен стоять в конце, иначе вывод будет неверным.
Это конец этого письма.
〰️〰️〰️〰️〰️〰️〰️〰️〰️〰️〰️〰️〰️〰️〰️〰️〰️〰️〰️〰️〰️〰️〰️〰️〰️〰️
⭐️⭐️⭐️⭐️⭐️⭐️⭐️⭐️⭐️⭐️ Великолепная разделительная линия ⭐️⭐️⭐️⭐️⭐️⭐️⭐️⭐️⭐️⭐️⭐️
〰️〰️〰️〰️〰️〰️〰️〰️〰️〰️〰️〰️〰️〰️〰️〰️〰️〰️〰️〰️〰️〰️〰️〰️〰️〰️
Затем обновите информацию об интеграцииnavigation
интеграция, если вы использовали более старую версиюreact native
знаю, что вreact-navigation
До подъема большинство разработчиков использовали официально предоставленныйNavigator
,доreact native
v0.44.3Объявлено заброшенным при запускеNavigator
.
Navigator
илиreact-navigation
, поэтому я не знаю, сколько подобных навигационных решений есть на рынке, но в этот раз, в период перерыва в проекте, я глубже разобрался с тремя самыми популярными навигаторами на рынке:
Это официально рекомендуется в
github
уже на1.35W+
🌟, авторReact Native
Сообщество поддерживается, на данный момент это самое популярноеReact Native
Навигационная библиотека. он полностью используетJavaScript
писать вместо использования родногоAPI
, который воссоздает некоторые подмножества. Эта опция позволяет пользователям настраивать любую часть навигационного опыта, не изучаяiOS
илиAndroid
Логика навигации. потому чтоReact Navigation的
Большая часть логики находится вJavaScript
вместо запуска в родном, так что любая блокировкаJavaScript
Ситуация с потоком приведет к появлению задержки. Также объяснитеreact navigation
Версия v1 сильно отличается от версии v2.Если вы хотите узнать о детской обуви, вы можете прочитать эту статью, которую я написал ранее [Реагировать на нативную мощную навигацию V2.0+ ](woo woo Краткое описание.com/fear/05 возражение 0 о 9 неплохо…).
В настоящее время в официальных документах четко указано:
Warning: in the next major version of React Navigation, to be released in Fall 2018, we will no longer provide any information about how to integrate with Redux and it may cease to work. Issues related to Redux that are posted on the React Navigation issue tracker will be immediately closed. Redux integration may continue to work but it will not be tested against or considered when making any design decisions for the library.
Some folks like to have their navigation state stored in the same place as the rest of their application state. Think twice before you consider doing this, there is an incredibly good chance that you do not need to do this!. Storing your React Navigation state in your own Redux store is likely to give you a very difficult time if you don't know what you're doing.
If your only reason for doing this is that you want to be able to perform navigation actions from outside of your components (eg: from a Redux middleware), you can learn more about this in navigating without the navigation prop.
переводить:
Предупреждение: в следующей большой версии React Navigation, которая выйдет осенью 2018 года, мы больше не будем предоставлять информацию о том, как интегрировать Redux, и ее поддержка может быть прекращена. Проблемы с Redux, опубликованные в системе отслеживания проблем React Navigation, также будут немедленно закрыты. Интеграция Redux может продолжать работать, но не будет тестироваться или учитываться при принятии каких-либо проектных решений для библиотеки.
Некоторым людям нравится хранить свое состояние навигации в том же месте, что и остальную часть состояния приложения. Подумайте дважды, прежде чем решиться на это, но есть очень большая вероятность, что вам не придется этого делать!. Сохранение состояния React Navigation в вашем собственном магазине Redux может быть затруднено, если вы не знаете, что делаете.
Если ваша единственная причина сделать это — иметь возможность выполнять действия навигации извне компонента (например, из промежуточного программного обеспечения Redux), вы можете узнать больше оНавигация без навигационной опорыИнформация.
В переводе на простой язык:React Navigation
Совместимость больше не будет преднамеренно учитываться в следующей версии.Redux
, его можно использовать, но есть проблема, которая должна решаться сама собой.
Эй, я не понимаю, почему чиновник делает это, может быть, это для снижения затрат на обслуживание, но это, несомненно, неразумный выбор, и могут быть сюрпризы, так что давайте пока с нетерпением ждем этого. Если проект объединяетredux
Я лично не рекомендую использоватьReact Navigation
.
это основано на
React Navigation
, но обеспечивает другоеAPI
. существуетgithub
уже на7600+
🌟, который позволяет вам определять переходы сцен в одном центральном месте без передачи объекта навигатора и легко доступен в любом месте вашего кода.Последняя бета-версия 4, среди прочих изменений, представляет поддержку ящиков и конечный автомат навигации на основе Mob-X, который отделяет логику навигации от уровня представления.
Другая популярная навигационная библиотека предоставляетсяWixРазработано командой с открытым исходным кодом
React Native Navigation
,существуетgithub
близко к9000+
🌟, его самым большим преимуществом является 100% нативная навигация по платформам с наложением межплатформенного интерфейса, с готовымиRedux
служба поддержки.тебе следует
iOS
а такжеAndroid
Настройте этот пакет индивидуально, включая ссылкуiOS
библиотека, обновлениеiOS
путь поиска заголовка, вAndroid
MainActivity
средняя протяженностьSplashActivity
вместоReactActivity
и несколько других шагов, подробно описанных в документации. После этого вам просто нужно зарегистрировать все экраны приложения и запустить приложение.
В текущем официальном документе также предлагается:
Note: example redux is deprecated. Since we did not have enough time and resources to maintain both example projects, we decided to stop maintaining the redux example. This does not mean redux can't be used with react-native-navigation (In fact, we use redux in the Wix app). For a working example project which uses redux with RNN you can refer to JuneDomingo/movieapp.
переводить:
Примечание. Пример избыточности устарел. Поскольку у нас недостаточно времени и ресурсов для поддержки этих двух проектов-примеров, мы решили прекратить поддержку избыточных примеров. Это не означает, что redux нельзя использовать с react-native-navigation (на самом деле мы используем redux в приложении Wix). Для рабочего примера проекта, использующего редукцию с RNN, вы можете обратиться к JuneDomingo/movieapp.
Подводя итог: лично отreact navigation
а такжеreact-native-navigation
официальная параRedux
отношение совершенно другое, по крайней мереWix
используется внутриRedux
. Если в проекте необходимо использоватьRedux
, мой первый выбор был быReact Native Navigation
, потому что это чисто родной опыт, иRedux
Поддержка хорошая. Если не использоватьRedux
В проекте вы можете попробовать первые два вида навигации, эти два вида навигации также хороши, очень близки к родному опыту.
Структурный анализ
Использование выбора навигации по этой статьеreact-native-navigation
,оreact-native-navigation
Информацию об интеграции и использовании API см.официальная документация, если вы хотите узнатьReact Navigation
используется вredux
кликните сюдаилиздесь, следующий код файла изменен и добавлен в этом обновлении
index.js
//discard (废弃)
import { AppRegistry } from 'react-native';
AppRegistry.registerComponent('ReduxForReactNativeDemo', () => App);
//new
import App from './App';
new App();
App.js
import React, { Component } from 'react'
import { applyMiddleware, createStore } from 'redux'
import { createLogger } from 'redux-logger'
import { Provider } from 'react-redux'
import thunk from 'redux-thunk'
import rootReducer from './js/reducers'
import { Navigation } from 'react-native-navigation'
import { registerScreens } from './js/components/screens'
const logger = createLogger();
const store = createStore(
rootReducer,
applyMiddleware(thunk, logger)
);
registerScreens(store, Provider);
export default class App extends Component {
constructor(props){
super(props);
this._startApp();
}
_startApp = () => {
Navigation.startTabBasedApp({
tabs: [
{
label: 'Home',
screen: 'ReduxForReactNativeDemo.HomeScreen',
icon: require('./res/img/ic_home.png'),
// selectedIcon: require('./img/checkmark.png'),
title: 'Home',
overrideBackPress: false,
navigatorStyle: {}
},
{
label: 'Posts',
screen: 'ReduxForReactNativeDemo.PostsScreen',
icon: require('./res/img/ic_news.png'),
// selectedIcon: require('./img/checkmark.png'),
title: 'Posts',
navigatorStyle: {}
}
]
});
}
}
по сравнению с предыдущей версиейdemo
,весьApp.js
Код файла в основном изменен
другие изменения
существуетcomponents
Добавить в каталогscreens
каталог, который содержит файлы интерфейса один за другим, и каждый интерфейс состоит из нескольких компонентов.
-
Group.js
переименовать вHomeScreen.js
. - новый
PostsDetail.js
,PostsScreen.js
,index.js
,index.js
Роль файла заключается в регистрации всех файлов интерфейса. -
Posts.js
новыйitem
Нажмите на событие, чтобы войти в интерфейс сведений о списке. -
LoadPosts.js
68
новая линия{...this.props}
, чтобыPosts.js
внутри черезthis.props
получатьnavigator
. - Добавить в корневой каталог
res
папка ресурсов.
Суммировать:
На этом структурный анализ заканчивается, давайте поговорим о следующих трех.demo
Такое ощущение, что это стабильная версия. Честно говоря, за это время я многому научился, а также столкнулся с различными проблемами в процессе практики, перечитал большое количество ресурсов и задал много вопросов, в итоге решал их один за другим, и ответы потихоньку всплывали. видел многоdemo
Существуют всевозможные странные способы написания, и редко можно увидеть стандартную инженерную структуру проекта.Большинство из них предназначены для достижения эффектов, и такая структура проекта не может быть использована в реальных проектах. моя статья, я рассказал мне, почему я потратил время и силы на написание этой технической статьи. Я буду применять эту инженерную структуру для будущей интеграцииredux
в проекте. На самом деле найти хороший учебный материал непросто. Если вы считаете, что он хорош, вы можете зажечь ❤️, чтобы больше людей могли его открыть для себя.
пасхальные яйца
прикреплятьdemo, добро пожаловать ❤️⭐️👏, чтобы указать на ошибки или опубликовать свое собственное мнение, чтобы обсудить и поддержать друг друга. 🤝
Уведомление
непосредственныйclone
Если вы запустите его, вы увидите содержимое последнего (v3) обновления по умолчанию.demo
,
воплощать в жизньgit tag
Есть три демонстрации, которые можно увидетьtag
, если перейти на два предыдущих обновленияdemo
Содержание: Выполнить в корневом каталоге:
перейти на версию 0.1
git checkout -b dev v0.1
перейти на версию 0.2
git checkout -b dev v0.2