我使用React-Native-Router-Flux来路由我的应用。问题是,当redux状态发生变化时,路由器下的所有组件都会被重新呈现,而不仅仅是当前的#34;成分
因此,假设路由器下有两个组件:注册和登录,两者共享相同的 authenticationReducer 。每当身份验证事件(例如用户注册或登录)失败时,我都希望显示错误警报。
问题是,当从其中一个组件触发错误时,会同时显示两个警报,每个组件一个警报。我假设当前我在Register场景中,只会从Register组件显示错误警告。
然而,似乎两个组件都会在redux状态发生变化时重新呈现,并且我看到2个警报(在下面的示例中,来自REGISTER'以及'来自SIGNIN的错误' )。
以下是组件:
export default class App extends Component {
render() {
return (
<Provider store={store}>
<Router>
<Scene key='root'>
<Scene key='register' component={Register} type='replace'>
<Scene key='signin' component={SignIn} type='replace'>
</Scene>
</Router>
</Provider>
);
}
}
class Register extends Component {
render() {
const { loading, error } = this.props;
if (!loading && error) {
Alert.alert('Error from REGISTER');
}
return <View>...</View>;
}
}
const mapStateToProps = (state) => {
return {
loading: state.get("authenticationReducer").get("loading"),
error: state.get("authenticationReducer").get("error"),
};
};
export default connect(mapStateToProps)(Register);
class SignIn extends Component {
render() {
const { loading, error } = this.props;
if (!loading && error) {
Alert.alert('Error from SIGNIN');
}
return <View>...</View>;
}
}
const mapStateToProps = (state) => {
return {
loading: state.get("authenticationReducer").get("loading"),
error: state.get("authenticationReducer").get("error"),
};
};
export default connect(mapStateToProps)(SignIn);
如何更改此设置,以便当我当前在“注册场景”时只显示REGISTER错误消息,反之亦然?
由于
答案 0 :(得分:0)
由于react-native-router-flux的工作方式,所有以前的页面仍然是&#34; open&#34;并安装。我不完全确定这个解决方案是否有效,因为这个奇怪的怪癖。
遵循React非常严格(简单)的规则:渲染中没有副作用。现在你实际上在那里做了副作用,即Alert.alert()。渲染可以在实际渲染之前调用一次,两次,无论多少次。现在,这将导致警报多次出现!
尝试将其放入componentDidUpdate中,并将其与之前的道具进行比较,以确保它只发生一次:
componentDidUpdate(prevProps) {
if (this.props.error && this.props.error !== prevProps.error) {
// Your alert code
}
}
我并不完全相信这会真正起作用,因为组件仍会更新,因为它通过react-native-router-flux保存在内存中,但它至少会有更少的怪癖。
答案 1 :(得分:0)
我通过创建ErrorContainer来监视错误并将其连接到使用react-native-simple-modal在整个应用程序中呈现单个错误模式的组件来解决这个问题。
这种方法很好,因为您只需要定义一次错误逻辑和组件。 react-native-simple-modal组件使用起来非常简单。我有一个错误存储库,它是一个我可以从任何地方推送错误的数组。在容器mapStateToProps中,我只是抓取数组中的第一个错误(FIFO),因此多个错误模式只是&#34;堆叠&#34;,当你关闭时,如果存在则会打开。
容器:
const mapStateToProps = (
state ) => {
return {
error: state.errors.length > 0 ? state.errors[0] : false
};
};
减速器:
export default function errors (state = [], action) {
switch (action.type) {
case actionTypes.ERRORS.PUSH:
return state.concat({
type: action.errorType,
message: action.message,
});
case actionTypes.ERRORS.POP:
return state.slice(1);
case actionTypes.ERRORS.FLUSH:
return [];
default:
return state;
}
}