React-Native SwitchNavigator не предоставляет новые реквизиты в корне - PullRequest
0 голосов
/ 25 ноября 2018

У меня проблема с получением новых реквизитов в навигаторе корневого стека.У меня есть 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 голосов
/ 25 ноября 2018

до

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

Редуктор имеет проблемы.Я сделал абсолютно новый массив.Оно работает!Но я думаю, что это не нормально :) 1007 *

0 голосов
/ 25 ноября 2018

Похоже, это связано с тем, что вы обновляете свое локальное состояние (this.state.categories) на основе свойства categories, только на этапе componentWillMount, но не при обновлении реквизита (что должно произойти после отправки новогоdata).

Попробуйте использовать this.props.categories непосредственно в компоненте CategoriesListScreen.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...