Я предлагаю использовать некоторый контейнер состояний для приложения, чтобы легко манипулировать им с пользователем.Наиболее распространенным решением является использование Redux
.С помощью redux вы сможете иметь глобальное состояние своего приложения.Как правило, все пользовательские данные хранятся в нем.https://redux.js.org/ Другое решение - использовать MobX
с простым доступом к магазину.Он не использует шаблон потока, если вам это не нравится.Если вы не хотите использовать глобальный магазин, вы можете использовать HOCs
для распространения ваших пользовательских данных.Наконец, вы можете использовать Context
для реакции, но это плохой подход.
Давайте, например, выберем самый популярный представитель архитектуры Flux - Redux.
Первый слой - слой View,Здесь мы отправим некоторые действия для изменения глобальных данных, например, пользовательские данные.
import { connect } from 'react-redux'
import { bindActionCreators } from 'redux'
import { logIn, logOut } from 'actions'
export default class Page extends React.Component {
useEffect(() => {
firebase.auth().onAuthStateChanged((user) => {
logIn(user)
} else {
logOut()
})
}, [])
render () {
...
}
}
const mapDispatchToProps = dispatch => bindActionCreators({
logIn,
logOut
}, dispatch)
export default connect(null, mapDispatchToProps)(App)
Второй уровень - это действия.Здесь мы работаем со своими данными, работаем с API, форматным состоянием и так далее.Основная цель действий - создание данных для передачи их в редуктор.
actions.js
export const logIn = user => dispatch => {
// dispatch action to change global state
dispatch({
type: 'LOG_IN',
payload: user
})
}
export const logOut = user => dispatch => {
dispatch({ type: 'LOG_OUT' })
}
Последнее - это редукторы.Единственная цель из них - изменить состояние.Мы подписываемся здесь на некоторые действия.Редуктор всегда должен быть чистой функцией.Состояние не должно быть изменено, только перезаписано.
appReducer.js
const initialState = {
user: null
}
export default function appReducer (state = initialState, action) {
const { type, payload } = action
switch(type) {
case 'LOG_IN':
return {
...state,
user: payload
}
case: 'LOG_OUT':
return {
...state,
user: null
}
}
}
Тогда мы можем работать с глобальным состоянием приложения, когда захотим.Чтобы сделать это, мы должны использовать библиотеку react-redux
и Provider
HOC
const App = () =>
<Provider store={store}>
<Navigation />
</Provider>
Теперь мы можем иметь доступ к любым хранилищам внутри любого компонента, даже реагируя с избыточностью connect
HOF.Он работает с React Context API внутри него.
const Page2 = ({ user }) => {
//... manipulate with user
}
// this function gets all stores that you have in the Provider.
const mapStateToProps = (state) => {
user: state.user
}
export default connect(mapStateToProps)(Page2)
Кстати, вы должны выбрать промежуточное программное обеспечение для работы с асинхронным кодом в Redux.Самым популярным, что используется в моем примере, является redux-thunk
.Более подробную информацию вы можете найти в официальной документации.Там вы можете найти информацию о том, как выполнить начальную настройку магазина