С тех пор я нашел лучшее решение.Я создал HOC, который я сейчас вызываю на любом Компоненте, функциональном или нет, который требует доступа к магазину.Это дает мне доступ к состоянию магазина и все функции в реквизитах.Это означает, что я могу свободно использовать компонент так, как он был задуман, перехватывает и все.
Вот как это выглядит:
WithUnstated.js
import React, { PureComponent } from "react";
import { Subscribe } from "unstated";
import MainStore from "../store/Main";
const withUnstated = (
WrappedComponent,
Stores = [MainStore],
navigationOptions
) =>
class extends PureComponent {
static navigationOptions = navigationOptions;
render() {
return (
<Subscribe to={Stores}>
{(...stores) => {
const allStores = stores.reduce(
// { ...v } to force the WrappedComponent to rerender
(acc, v) => ({ ...acc, [v.displayName]: { ...v } }),
{}
);
return <WrappedComponent {...allStores} {...this.props} />;
}}
</Subscribe>
);
}
};
export default withUnstated;
Используетсякак в этом примере Header:
import React from "react";
import { Text, View } from "react-native";
import styles from "./styles";
import { states } from "../../services/data";
import withUnstated from "../../components/WithUnstated";
import MainStore from "../../store/Main";
const Header = ({
MainStore: {
state: { vehicle }
}
}) => (
<View style={styles.plateInfo}>
<Text style={styles.plateTop}>{vehicle.plate}</Text>
<Text style={styles.plateBottom}>{states[vehicle.state]}</Text>
</View>
);
export default withUnstated(Header, [MainStore]);
Так что теперь вам не нужно создавать миллион компонентов оболочки за все время, когда ваш магазин будет доступен вне функции рендеринга.Как еще один положительный герой, HOC принимает множество магазинов, что делает его полностью готовым к работе.И - это работает с вашими навигационными параметрами!
Просто не забудьте добавить displayName в свои магазины (ES-Lint предложит вам в любом случае).
Вот как выглядит простое хранилище:
import { Container } from "unstated";
class NotificationStore extends Container {
state = {
notifications: [],
showNotifications: false
};
displayName = "NotificationStore";
setState = payload => {
console.log("notification store payload: ", payload);
super.setState(payload);
};
setStateProps = payload => this.setState(payload);
}
export default NotificationStore;