很抱歉新手问题,但我仍然对使用React Native和Mobx感到困惑。我想为可变主题创建全局商店。
import { observable, action, computed } from "mobx";
class ThemeStore {
@observable primaryColor = "#FFCC33" ;
@observable secondaryColor = "#4E3D2D";
@observable whiteColor = "#FFF";
constructor() {
}
}
export const themeStore = new ThemeStore();
对于组件,themeStore既可以用于props,也可以用于注入。但问题是如何将它与非组件一样用于StyleSheet,所以我可以在样式const中使用primaryColor。
我试过了:
@inject("themeStore")
const styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: "center",
alignItems: "center",
backgroundColor: themeStore.primaryColor
},
logo: {
width: 20,
height: 20
}
});
但是收到错误必须将前导装饰符附加到类声明中。所以我想问一下创建用于非组件的可变全局存储(变量)的正确和正确方法是什么? 谢谢。
更新了代码示例:
@inject("foodDataStore", "navStore", "themeStore", "placeDataStore")
@observer
export class PlaceForm extends React.Component {
constructor(props) {
super(props);
let foodDataStore = this.props.foodDataStore;
let navStore = this.props.navStore;
let themeStore = this.props.themeStore;
let placeDataStore = this.props.placeDataStore;
this.state = {
foodDataStore,
navStore,
placeDataStore,
themeStore,
placeName: "",
placeImage: "",
address: "",
category: "",
foods: [],
location: "",
operationHours: "",
telephone: "",
email: "",
tags: [],
validationPlaceNameMessage: "",
validationPlaceImageMessage: "",
validationAddressMessage: "",
validationCategoryMessage: "",
validationLocationMessage: "",
validationOperationHoursMessage: "",
validationTelephoneMessage: "",
validationEmailMessage: ""
};
}
static navigationOptions = ({ navigation }) => ({
title: "New Place",
headerLeft: <BackButton navigation={navigation} />,
headerRight: null,
headerTintColor: COLOR_SECONDARY_LIGHT,
headerStyle: {
backgroundColor: COLOR_PRIMARY_LIGHT,
marginTop: 20
}
});
render() {
const { navigation } = this.props.navigation;
const { styleSheet } = this;
let Tags = this.state.tags.map((item, index) => {
return (
<FormInput
key={index}
value={"#" + item}
editable={false}
selectTextOnFocus={false}
/>
);
});
return (
<View style={styleSheet.container}>
<ScrollView>
<Text h4 style={styleSheet.title}>
Register New Place
</Text>
<FormLabel>Place Name</FormLabel>
<FormInput
onChangeText={name => this.validatePlaceName(name)}
placeholder="Place Name..."
/>
<FormValidationMessage>
{" "}
{this.state.validationPlaceNameMessage}{" "}
</FormValidationMessage>
<FormLabel>Category</FormLabel>
<FormInput
onChangeText={category => this.validateCategory(category)}
placeholder="Category..."
/>
<FormValidationMessage>
{this.state.validationCategoryMessage}
</FormValidationMessage>
<FormLabel>Image</FormLabel>
<FormInput
onChangeText={imageSource => this.validatePlaceImage(imageSource)}
placeholder="Image..."
/>
<FormValidationMessage>
{this.state.validationPlaceImageMessage}
</FormValidationMessage>
<FormLabel>Address</FormLabel>
<FormInput
onChangeText={address => this.validateAddress(address)}
placeholder="Address..."
/>
<FormValidationMessage>
{this.state.validationAddressMessage}
</FormValidationMessage>
<View style={{ flex: 1, flexDirection: "row" }}>
<FormLabel>Tags</FormLabel>
<Icon
name={"md-add-circle"}
size={24}
type="ionicon"
color={this.state.themeStore.primaryLightColor}
onPress={() => {
this.addTag();
}}
style={styleSheet.iconAdd}
/>
</View>
<FormInput
placeholder="Tags..."
onChangeText={tag => {
this.setState({ tag });
}}
value={this.state.tag}
selectTextOnFocus={false}
/>
{Tags}
<FormValidationMessage />
<Button
style={styleSheet.button}
title="Register Place"
borderRadius={20}
backgroundColor={this.state.themeStore.primaryLightColor}
onPress={this.submitNewFood}
/>
<View style={{ height: 25, backgroundColor: "white" }} />
</ScrollView>
</View>
);
}
@computed
get styleSheet() {
const { themeStore } = this.props;
const styles = StyleSheet.create({
contentContainer: {
paddingVertical: 20
},
container: {
flex: 1,
marginTop: 0,
backgroundColor: "white"
},
logoContainer: {
alignItems: "center",
justifyContent: "center",
marginBottom: 20
},
logo: {
width: 50,
height: 50
},
title: {
textAlign: "center",
marginBottom: 20
},
button: {
marginTop: 20,
...Platform.select({
ios: {
width: 350
},
android: {
width: 100
}
}),
height: 48,
marginBottom: 20,
alignSelf: "center"
},
rating: {
marginLeft: 15,
backgroundColor: "transparent"
},
iconAdd: {
marginTop: 10
},
iconClose: {
...Platform.select({
ios: {
marginTop: 20
},
android: {
alignSelf: "flex-end"
}
})
}
});
return styles;
}
}
答案 0 :(得分:2)
您可以在React组件中使用computed,以便在更改observable时更新StyleSheet
:
// themeStore.js
class ThemeStore {
@observable primaryColor = "#FFCC33" ;
@observable secondaryColor = "#4E3D2D";
@observable whiteColor = "#FFF";
}
export const themeStore = new ThemeStore();
// yourComponent.js
@inject("themeStore") @observer
class YourComponent extends React.Component {
@computed get styleSheet() {
const { themeStore } = this.props;
const styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: "center",
alignItems: "center",
backgroundColor: themeStore.primaryColor
},
logo: {
width: 20,
height: 20
}
});
return styles;
}
render() {
const { styleSheet } = this;
return (
<div className={styleSheet.container}>
<span className={styleSheet.logo}> Logo </span>
</div>
);
}
}