0

我正在使用 React Native,我正在尝试通过向商店发送操作来更新我的 HomeScreen 组件,但是当商店的状态发生变化时,该组件不会自动重新渲染,我不确定是不是因为我连接不正确,或者我的导航设置不正确。

我已经尝试了标准的 Redux 语法,连接我的组件,调度一个动作,并更新减速器。但是,尽管状态有新的变化,但我的组件不会在状态变化时重新渲染。

这是我的组件的样子:

import React, { Component } from 'react';
import { connect } from 'react-redux';
import { fetchDebts } from '../../actions';
import HomeButtons from '../Components/Buttons';
import DebtNames from '../Components/DebtNames';
import { Container, Header, Body, Title, Text, Spinner } from 'native-base';
import { StyleSheet } from 'react-native';

class HomeScreen extends Component {
    constructor(props) {
        super(props);
        this.state = { iconClicked: false };
    }

    componentDidMount() {
        const { fetchData } = this.props;
        fetchData();
    }

    onRightIcon = debtId => {
        const { iconClicked } = this.state;
        this.setState({
            iconClicked: !iconClicked,
            debtId
        });
    };

    onItemDeleted = async id => {
        try {
            await deleteData(id);
            this.setState({
                debts: await fetchData()
            });
        } catch (e) {
            console.log(e);
        }
    };

    render() {
        const { iconClicked, debtId } = this.state;
        const { debts, navigation, loading } = this.props;
        if (!debts) {
            return <Spinner color="blue" style={{ alignSelf: 'center', justifyContent: 'center' }} />;
        }
        return (
            <Container style={{ backgroundColor: '#083D77' }}>
                <Header style={{ backgroundColor: '#8B2635', marginTop: checkIfIos() ? 0 : 20 }}>
                    <Body>
                        <Title style={{ color: '#E6E6E9', alignSelf: 'center' }}>Debt Manager</Title>
                    </Body>
                </Header>
                <HomeButtons navigation={navigation} />
                <Text style={style.textStyle}>Recently Added Items</Text>
                {debts && (
                    <DebtNames
                        debts={debts}
                        iconClicked={iconClicked}
                        debtId={debtId}
                        onRightIcon={this.onRightIcon}
                        onItemDeleted={this.onItemDeleted}
                    />
                )}
            </Container>
        );
    }
}

const mapStateToProps = state => ({
    debts: state.debts.items,
    loading: state.debts.loading,
    error: state.debts.error
});

const mapDispatchToProps = dispatch => {
    return {
        fetchData: () => dispatch(fetchDebts())
    };
};

export default connect(
    mapStateToProps,
    mapDispatchToProps
)(HomeScreen);

我的行动:

export const fetchDebtsBegin = () => {
    return {
        type: FETCH_DEBTS_BEGIN
    };
};

export const fetchDebtsSuccess = debts => {
    return {
        type: FETCH_DEBTS_SUCCESS,
        payload: debts
    };
};

export const fetchDebtsFailure = error => ({
    type: FETCH_DEBTS_FAILURE,
    payload: { error }
});

export const fetchDebts = () => {
    return (dispatch, getState) => {
        dispatch(fetchDebtsBegin());
        fetchData()
            .then(res => {
                dispatch(fetchDebtsSuccess(res.data));
            })
            .catch(err => {
                dispatch(fetchDebtsFailure(err));
            });
};
};

我的减速机:

const initialState = {
    items: [],
    loading: false,
    error: null
};

export default fetchDebtsReducer = (state = initialState, action) => {
    switch (action.type) {
        case FETCH_DEBTS_BEGIN:
            return {
                ...state,
                loading: true
            };
        case FETCH_DEBTS_SUCCESS:
            return {
                ...state,
                items: [...action.payload],
               //also tried items: action.payload
                loading: false
            };
        case FETCH_DEBTS_FAILURE:
            return {
                ...state,
                loading: false,
                error: action.payload.error
            };
           };
}

如果有帮助,这是我的导航:

import React from 'react';
import { createBottomTabNavigator, createAppContainer, stackNavigator } from 'react-navigation';
import { defaultNavigationOptions } from './utils';
import { connect } from 'react-redux';
import Icon from 'react-native-vector-icons/MaterialIcons';
import HomeScreen from './screens/HomeScreen';
import AddPaymentScreen from './screens/AddPaymentScreen';

const TabNavigator = createBottomTabNavigator(
    {
        Home: {
            screen: HomeScreen,
            navigationOptions: {
                tabBarLabel: 'HOME',
                tabBarIcon: ({ tintColor }) => <Icon name="home" size={24} color={tintColor} />
            }
        },
        AddPayment: {
            screen: AddPaymentScreen,
            navigationOptions: {
                tabBarLabel: 'ADD PAYMENT',
                tabBarIcon: ({ tintColor }) => <Icon name="add-circle" size={24} color={tintColor} />
            }
    },
    {
        initialRouteName: 'Home'
    },
    {
        defaultNavigationOptions
    }
);

const AppContainer = createAppContainer(TabNavigator);

export default connect(null)(AppContainer);

和 App.js:

class App extends React.Component {
    constructor(props) {
        super(props);
        this.state = { isReady: false };
    }
    async componentWillMount() {
        await Font.loadAsync({
            Roboto: require('native-base/Fonts/Roboto.ttf'),
            Roboto_medium: require('native-base/Fonts/Roboto_medium.ttf')
        });
        this.setState({ isReady: true });
    }

    render() {
        const { isReady } = this.state;
        if (!isReady) {
            return <AppLoading />;
        }
        return (
            <Provider store={store}>
                <AppContainer />
            </Provider>
        );
    }
}

我希望 HomeScreen 组件在商店中的状态更改时自动重新渲染。但唯一发生的事情是商店正在更新,并且组件不会自动重新渲染。

任何帮助将不胜感激。

4

1 回答 1

0

我发现了这个问题。

在我试图添加债务的组件(我没有在此处列出)中,我没有定义mapStateToProps,因此我无法在我的操作中访问调度功能。之后,我可以从 POST 操作中调用我的 fetch 操作。

希望这对将来的任何人都有帮助。

于 2019-09-09T05:43:08.110 回答