首页 > 解决方案 > 应用通过 Redux 获取数据后重启

问题描述

我正在尝试在渲染之前将用户数据从 Firebase 提取到应用场景。通过 action 获取数据并从 reducer 调用 dispatch 后,场景不显示。相反,应用程序重新启动。这不是崩溃,因为我可以在控制台中看到组件的日志,这些日志仅在应用程序启动时显示)。

我是 React Native 和 Redux 的新手,但这种行为对我来说没有意义。

PlaceDetail.js - 应该获取数据的组件

import React, { Component } from 'react';
import { View, Text, ImageBackground } from 'react-native';
import { connect } from 'react-redux';
import ParallaxScrollView from 'react-native-parallax-scroll-view';
import Modal from 'react-native-modal';
import Icon from 'react-native-vector-icons/AntDesign';
import { AirbnbRating } from 'react-native-elements';
import { Actions } from 'react-native-router-flux';
import { ButtonSmall, OneLineDetail, PlaceDescription, Rating } from './common';
import { addRatingToPlace, userPlaceDataFetch } from '../actions';

...

class PlaceDetail extends Component {
    state = { showModal: false };

    componentWillMount() {
        this.props.userPlaceDataFetch(this.props.place.uid); // calling an action
    }

    onArrowPress() {
        Actions.pop();
    }

    onVisitButtonPress() {
        this.setState({ showModal: true });
    }

    ratingComplete(pUID, value) {
        this.props.addRatingToPlace(value, pUID);
    }

    render() {
        return (
            <View style={containerStyle}>
                <Modal 
                    isVisible={this.state.showModal}
                    onBackdropPress={() => this.setState({ showModal: false })}    
                    onSwipeComplete={() => this.setState({ showModal: false })}
                    swipeDirection="left"
                >
                    <View style={{ flex: 1, justifyContent: 'center', alignItems: 'center' }}>
                        <Text style={modalTitleStyle}>HODNOTENIE</Text>
                        <AirbnbRating
                            count={5}
                            reviews={['Slabé', 'Ujde', 'V pohode', 'Super', 'Vynikajúce']}
                            defaultRating={userDataDetail.rate}
                            size={20}
                            showRating
                            onFinishRating={this.ratingComplete.bind(this, uid)}
                        />
                    </View>
                </Modal>

...

const mapStateToProps = (state) => {
    const userDataDetail = state.userData;

    return { userDataDetail };
};

export default connect(mapStateToProps, { addRatingToPlace, userPlaceDataFetch })(PlaceDetail);

UserDataActions.js

import firebase from '@firebase/app';
import '@firebase/auth';
import '@firebase/database';
import { USER_PLACE_DATA_FETCH_SUCCESS } from './types';

export const userPlaceDataFetch = (currentPlaceUID) => {
    const { currentUser } = firebase.auth();
    return (dispatch) => {
        firebase.database().ref(`users/${currentUser.uid}/ratings/${currentPlaceUID}`)
            .on('value', snapshot => {
                console.log('snapshot.val:', snapshot.val());
                dispatch({ type: USER_PLACE_DATA_FETCH_SUCCESS, payload: snapshot.val() });
            });
    };
};

UserDataReducer.js

import { USER_PLACE_DATA_FETCH_SUCCESS } from '../actions/types';

const INITIAL_STATE = {
    showModal: false,
};

export default (state = INITIAL_STATE, action) => {
    switch (action.type) {
        case USER_PLACE_DATA_FETCH_SUCCESS:
            return action.payload;
        default:
            return state;
    }
};

减速器/index.js

import { combineReducers } from 'redux';
import AuthReducer from './AuthReducer';
import ProfileReducer from './ProfileReducer';
import ListReducer from './ListReducer';
import MapReducer from './MapReducer';
import DetailReducer from './DetailReducer';
import UserDataReducer from './UserDataReducer';

export default combineReducers({
    auth: AuthReducer,
    prof: ProfileReducer,
    places: ListReducer,
    maps: MapReducer,
    detail: DetailReducer,
    userData: UserDataReducer
});

应用程序.js

import React, { Component } from 'react';
import { Provider } from 'react-redux';
import { createStore, applyMiddleware } from 'redux';
import ReduxThunk from 'redux-thunk';
//import firebase from '@firebase/app';
import Firebase from './Firebase';
import Router from './Router';
import reducers from './reducers';

class App extends Component {
    render() {
        return (
            <Provider store={createStore(reducers, {}, applyMiddleware(ReduxThunk))}>
                <Router />
            </Provider>
        );
    }
}

export default App;

路由器 - 查看我的场景/组件是如何组织的

<Router>
                <Scene key="root">
                    <Scene key="isLogged" hideNavBar initial>
                        <Scene key="splash" component={Splash} hideNavBar />
                    </Scene>
                    <Scene key="auth" hideNavBar>
                        <Scene key="login" component={LoginForm} hideNavBar />
                    </Scene>
                    <Scene 
                        key="main" 
                        tabs
                        tabBarStyle={{ backgroundColor: '#10172C' }} 
                        hideNavBar
                    >
                        <Scene 
                            key="list" 
                            component={ListOfPlaces} 
                            icon={iconList}
                            title="Zoznam miest" 
                            initial
                            hideNavBar 
                            dataPlaces={this.props.places}
                        />
                        <Scene 
                            key="map" 
                            component={MapOfPlaces} 
                            icon={iconMap}
                            title="Mapa" 
                            hideNavBar
                            dataPlaces={this.props.places}
                        />
                        <Scene 
                            key="profile" 
                            component={Profile}
                            icon={iconUser}
                            title="Profil"
                            hideNavBar
                        />
                    </Scene>
                    <Scene 
                        key="place"
                        component={PlaceDetail}
                        hideNavBar
                    />
                </Scene>
            </Router>

标签: reactjsreact-nativereduxreact-redux

解决方案


const INITIAL_STATE = {
    rate: null, // init your relevant state fields here , or leave it empty
};

export default (state = INITIAL_STATE, action) => {
    switch (action.type) {
        case USER_PLACE_DATA_FETCH_SUCCESS:
            return { ...state, ...action.payload };
        default:
            return state;
    }
};

推荐阅读