React-Native SwitchNavigator不在root中提供新的道具

时间:2018-11-25 08:14:44

标签: react-native react-redux

我在根堆栈导航器中接收新道具时遇到问题。我在堆栈导航器中有2个屏幕:列表和编辑项目。在列表屏幕上,我单击一个编辑按钮,然后调度要存储的数据-它起作用。但是在编辑屏幕中,我编辑数据并调度带有新元素的新列表(用于测试)。列表屏幕不接收新列表。你能帮我吗?

App.js

const reducer = (state = initialState, action) => {
    switch (action.type) {
        case 'CATEGORIES_CHANGED':
            return {
                ...state,
                categories: action.data
            };

        case 'SET_CATEGORY_INFO':
            return {
                ...state,
                categoryInfo: action.data
            };
        default:
            return state;
    }
};

const store = createStore(reducer);

export default class App extends React.Component {

    render() {
        return (
            <Provider store={store}>
                    <AppNavigator/>
            </Provider>
        );
    }
}

AppNavigator.js

import React from 'react';
import { createSwitchNavigator } from 'react-navigation';
import MainTabNavigator from './MainTabNavigator';
import { connect } from 'react-redux';

const AppNavigator = createSwitchNavigator({

    Main: MainTabNavigator

});

export default AppNavigator;

MainTabNavigator.js

import React from 'react';
import {Platform} from 'react-native';
import {createStackNavigator, createBottomTabNavigator} from 'react-navigation';
import { connect } from 'react-redux';

...

const CategoriesStack = createStackNavigator({
    CategoriesListScreen: {
        screen: CategoriesListScreen,
    },
    CategoryInfoScreen: {
        screen: CategoryInfoScreen,
    },
    CategoryEditScreen: {
        screen: CategoryEditScreen,
    },
});

CategoriesStack.navigationOptions = {
    tabBarLabel: 'Categories',
    tabBarIcon: ({focused}) => (
        <TabBarIcon
            focused={focused}
            name={Platform.OS === 'ios' ? 'ios-link' : 'md-link'}
        />
    ),
};

...

const bottomTabNavigator = createBottomTabNavigator({
    CategoriesStack,
    ...
});

export default bottomTabNavigator;

CategoriesListScreen.js

import { connect } from 'react-redux';

class CategoriesListScreen extends React.Component {

    render() {
        const cats = this.state.categories;

        return (
            <ScrollView style={styles.container}>
                {cats.map((category, i) => {
                    return (
                        <TouchableOpacity key={category.id} style={
                            (i === cats.length - 1) ?
                                {...styles.categoryItem, ...styles.categoryItemLast} :
                                styles.categoryItem
                        } onPress={()=>{this.onPressCategory(category)}}>
                            <View style={{
                                ...styles.categoryLabel, ...{
                                    backgroundColor: category.color
                                }
                            }}>
                                <Icon name={category.icon} size={25} style={styles.categoryIcon}
                                      color={category.iconColor}/>
                            </View>

                            <Text>{category.title}</Text>
                        </TouchableOpacity>
                    )
                })}
            </ScrollView>
        );
    }

    componentWillReceiveProps(nextProps) {
        console.log(nextProps);
    }

    componentWillMount() {
        const categories = this.props.categories;
        this.setState({
            categories: categories
        });
    }

    onPressCategory(category) {
        this.props.setCategoryInfo(category);
        this.props.navigation.navigate('CategoryInfoScreen', {});
    }

}

function mapStateToProps(state) {
    return {
        categories: state.categories
    }
}

function mapDispatchToProps(dispatch) {
    return {
        setCategoryInfo: (category) => dispatch({ type: 'SET_CATEGORY_INFO', data: category })
    }
}

export default connect(mapStateToProps, mapDispatchToProps)(CategoriesListScreen)

CategoryEditScreen.js

import { connect } from 'react-redux';

class CategoryEditScreen extends React.Component {

    static navigationOptions = ({navigation}) => {
        return {
            title: 'Edit Category',
            headerRight: <Button onPress={() => {navigation.getParam('categoryChangedDispatch')()}} title="Save"/>
        }
    };

    render() {
        const category = this.state.category;
        ...
    }

    componentWillMount() {
        const category = this.props.categoryInfo;
        this.setState({
            category: category
        });
    }

    componentDidMount() {
        this.props.navigation.setParams({
            categoryChangedDispatch: this.categoryChangedDispatch.bind(this)
        });
    }

    categoryChangedDispatch() {
        let cats = this.props.categories;

        cats.push({
            id: 3,
            title: 'My third category',
            color: '#7495e7',
            icon: 'airplane',
            iconColor: '#2980B9'
        });

        this.props.categoryChanged(cats);
        this.props.navigation.navigate('CategoryInfoScreen', {});
    }

}

function mapStateToProps(state) {
    return {
        categories: state.categories,
        categoryInfo: state.categoryInfo
    }
}

function mapDispatchToProps(dispatch) {
    return {
        categoryChanged: (categories) => dispatch({ type: 'CATEGORIES_CHANGED', data: categories }),
    }
}

export default connect(mapStateToProps, mapDispatchToProps)(CategoryEditScreen)

2 个答案:

答案 0 :(得分:0)

这似乎与您基于this.state.categories属性更新本地状态(categories)的事实有关,仅在componentWillMount阶段才更新,而在道具更新时却没有。在您分发新数据后发生)。

尝试直接在this.props.categories组件中使用CategoriesListScreen

答案 1 :(得分:0)

之前

const reducer = (state = initialState, action) => {
switch (action.type) {
    case 'CATEGORIES_CHANGED':
        return {
            ...state,
            categories: action.data
        };
    default:
        return state;
}
};

之后

const reducer = (state = initialState, action) => {
switch (action.type) {
    case 'CATEGORIES_CHANGED':
        return {
            ...state,
            categories: Object.assign([], action.data)
        };
    default:
        return state;
}
};

减速器有问题。我做了绝对全新的阵列。有用!但我认为这不正常:)