MobX:观察到的组件在可观察到的变化后不会重新呈现
MobX: Observed Component does not rerender after observable change
我在 React Native 中有一个基本的 MobX 设置,但我的组件在 observable 更新后没有重新呈现,我似乎无法弄清楚为什么。
react-native 0.56.1;反应 16.4.1; mobx 4.5.0; mobx-反应 5.2.8
商店
class AppStore {
drawer = false;
toggleDrawer = () => {
this.drawer = !this.drawer;
}
}
decorate(AppStore, {
drawer: observable,
toggleDrawer: action
});
const app = new AppStore();
export default app;
组件
class _AppLayout extends React.Component {
constructor(props) {
super(props);
this.state = {
drawerAnimation: new Animated.Value(0)
};
}
UNSAFE_componentWillReceiveProps(nextProps) {
console.log('will not get called');
if (this.props.app.drawer !== nextProps.app.drawer) {
Animated.timing(this.state.drawerAnimation, {
toValue: nextProps.app.drawer === true ? 1 : 0,
duration: 500
}).start();
}
}
render() {
console.log("will only be called on first render");
const translateX = this.state.drawerAnimation.interpolate({
inputRange: [0, 1],
outputRange: [0, -(width - 50)]
});
return (
<Animated.View style={[styles.app, { transform: [{ translateX }] }]}>
<View style={styles.appContent}>
<RouterSwitch />
</View>
<View style={styles.appDrawer} />
</Animated.View>
);
}
}
const AppLayout = inject("app")(observer(_AppLayout));
触发器(来自不同组件)
<TouchableOpacity
onPress={() => {
app.toggleDrawer();
// will reflect the new value
console.log(app.drawer)
}}
style={styles.toggle}
/>
编辑:
经过一些调查,没有触发重新渲染,因为我没有在 render()
方法中使用商店,仅在 componentWillReceiveProps
中使用。这对我来说似乎很奇怪?
当我在渲染中使用商店时,即使只是分配一个变量,它也开始工作:
const x = this.props.app.drawer === false ? "false" : "true";
您需要在您的组件上使用 mobx-react
中的 observer
,最好使用装饰器。还要确保您在根组件上使用 Provider
商店
class AppStore {
@observable drawer = false;
@action toggleDrawer = () => {
this.drawer = !this.drawer;
console.log(this.drawer)
}
}
组件
const app = new AppStore();
export default app;
@observer
class AppLayout extends React.Component {
constructor(props) {
super(props);
this.state = {
drawerAnimation: new Animated.Value(0)
};
}
UNSAFE_componentWillReceiveProps(nextProps) {
console.log('will not get called');
if (this.props.app.drawer !== nextProps.app.drawer) {
Animated.timing(this.state.drawerAnimation, {
toValue: nextProps.app.drawer === true ? 1 : 0,
duration: 500
}).start();
}
}
render() {
console.log("will only be called on first render");
const translateX = this.state.drawerAnimation.interpolate({
inputRange: [0, 1],
outputRange: [0, -(width - 50)]
});
return (
<Provider app={app}>
<Animated.View style={[styles.app, { transform: [{ translateX }] }]}>
<View style={styles.appContent}>
<RouterSwitch />
</View>
<View style={styles.appDrawer} />
</Animated.View>
</Provider>
);
}
}
触发器
<TouchableOpacity
onPress={() => {
app.toggleDrawer();
// will reflect the new value
console.log(app.drawer)
}}
style={styles.toggle}
/>
根据 mobx 文档,
The observer function / decorator can be used to turn ReactJS components into reactive components. It wraps the component's render function in mobx.autorun to make sure that any data that is used during the rendering of a component forces a re-rendering upon change. It is available through the separate mobx-react package.
所以你需要使用 this.props.app.drawer
observer 组件的内部渲染功能来接收来自 mobx 的反应。
请参阅 this link 了解有关 mobx 如何以及何时做出反应的更多详细信息。
我在 React Native 中有一个基本的 MobX 设置,但我的组件在 observable 更新后没有重新呈现,我似乎无法弄清楚为什么。
react-native 0.56.1;反应 16.4.1; mobx 4.5.0; mobx-反应 5.2.8
商店
class AppStore {
drawer = false;
toggleDrawer = () => {
this.drawer = !this.drawer;
}
}
decorate(AppStore, {
drawer: observable,
toggleDrawer: action
});
const app = new AppStore();
export default app;
组件
class _AppLayout extends React.Component {
constructor(props) {
super(props);
this.state = {
drawerAnimation: new Animated.Value(0)
};
}
UNSAFE_componentWillReceiveProps(nextProps) {
console.log('will not get called');
if (this.props.app.drawer !== nextProps.app.drawer) {
Animated.timing(this.state.drawerAnimation, {
toValue: nextProps.app.drawer === true ? 1 : 0,
duration: 500
}).start();
}
}
render() {
console.log("will only be called on first render");
const translateX = this.state.drawerAnimation.interpolate({
inputRange: [0, 1],
outputRange: [0, -(width - 50)]
});
return (
<Animated.View style={[styles.app, { transform: [{ translateX }] }]}>
<View style={styles.appContent}>
<RouterSwitch />
</View>
<View style={styles.appDrawer} />
</Animated.View>
);
}
}
const AppLayout = inject("app")(observer(_AppLayout));
触发器(来自不同组件)
<TouchableOpacity
onPress={() => {
app.toggleDrawer();
// will reflect the new value
console.log(app.drawer)
}}
style={styles.toggle}
/>
编辑:
经过一些调查,没有触发重新渲染,因为我没有在 render()
方法中使用商店,仅在 componentWillReceiveProps
中使用。这对我来说似乎很奇怪?
当我在渲染中使用商店时,即使只是分配一个变量,它也开始工作:
const x = this.props.app.drawer === false ? "false" : "true";
您需要在您的组件上使用 mobx-react
中的 observer
,最好使用装饰器。还要确保您在根组件上使用 Provider
商店
class AppStore {
@observable drawer = false;
@action toggleDrawer = () => {
this.drawer = !this.drawer;
console.log(this.drawer)
}
}
组件
const app = new AppStore();
export default app;
@observer
class AppLayout extends React.Component {
constructor(props) {
super(props);
this.state = {
drawerAnimation: new Animated.Value(0)
};
}
UNSAFE_componentWillReceiveProps(nextProps) {
console.log('will not get called');
if (this.props.app.drawer !== nextProps.app.drawer) {
Animated.timing(this.state.drawerAnimation, {
toValue: nextProps.app.drawer === true ? 1 : 0,
duration: 500
}).start();
}
}
render() {
console.log("will only be called on first render");
const translateX = this.state.drawerAnimation.interpolate({
inputRange: [0, 1],
outputRange: [0, -(width - 50)]
});
return (
<Provider app={app}>
<Animated.View style={[styles.app, { transform: [{ translateX }] }]}>
<View style={styles.appContent}>
<RouterSwitch />
</View>
<View style={styles.appDrawer} />
</Animated.View>
</Provider>
);
}
}
触发器
<TouchableOpacity
onPress={() => {
app.toggleDrawer();
// will reflect the new value
console.log(app.drawer)
}}
style={styles.toggle}
/>
根据 mobx 文档,
The observer function / decorator can be used to turn ReactJS components into reactive components. It wraps the component's render function in mobx.autorun to make sure that any data that is used during the rendering of a component forces a re-rendering upon change. It is available through the separate mobx-react package.
所以你需要使用 this.props.app.drawer
observer 组件的内部渲染功能来接收来自 mobx 的反应。
请参阅 this link 了解有关 mobx 如何以及何时做出反应的更多详细信息。