防止react-native-router-flux渲染所有组件

时间:2016-08-31 02:16:36

标签: reactjs react-native redux react-router

我使用React-Native-Router-Flux来路由我的应用。问题是,当redux状态发生变化时,路由器下的所有组件都会被重新呈现,而不仅仅是当前的#34;成分

因此,假设路由器下有两个组件:注册登录,两者共享相同的 authenticationReducer 。每当身份验证事件(例如用户注册或登录)失败时,我都希望显示错误警报。

问题是,当从其中一个组件触发错误时,会同时显示两个警报,每个组件一个警报。我假设当前我在Register场景中,只会从Register组件显示错误警告。

然而,似乎两个组件都会在redux状态发生变化时重新呈现,并且我看到2个警报(在下面的示例中,来自REGISTER'以及'来自SIGNIN的错误' )。

以下是组件:

main.ios.js

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>
        );
    }
}



Register.js

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);



SignIn.js

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错误消息,反之亦然?

由于

2 个答案:

答案 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;
    }
}