0
votes

I have setup the redux store but when I try to make changes to the state using mapStateToProps and mapDispatchToProps I get always the default state. So at account.js I want to get the selected language and then add it to the redux store. I try to call it in other components but I always end up with reducers/Language.js defaultState. What I'm doing wrong?

Account.js

class Account extends React.Component {
        static navigationOptions = ({ navigation }) => {};

        constructor(props) {
            super(props);

            this.state = {
                language: {
                    sq: true,
                    en: false,
                    selected: '',
                },
            };
        }

        changeLanguage = (selected) => {
            if (this.state.sq) {
                this.setState({ selected: 'sq' });
            } else {
                this.setState({ selected: 'en' });
            }
        };


        render() {
            const navigation = this.props.navigation;
            return (
                <ScrollView>
                <View>
                        <ThemeProvider>
                            <TableView header={I18n.t('account.lang_label')}>
                                <CheckboxRow
                                    selected={this.state.language.sq}
                                    onPress={() => {
                                        this.setState(state => ({
                                            language: {
                                                sq: !state.language.sq,
                                                en: !state.language.en,
                                            },
                                        }));
                                        this.changeLanguage();
                                    }}
                                    title={I18n.t('account.albanian')}
                                />
                                <CheckboxRow
                                    selected={this.state.language.en}
                                    onPress={() =>
                                        this.setState(state => ({
                                            language: {
                                                en: !state.language.en,
                                                sq: !state.language.sq,
                                            },
                                        }))
                                    }
                                    title={I18n.t('account.english')}
                                />
                            </TableView>
                        </ThemeProvider>
                    </View>
                                </ScrollView>
            );
        }
    }

    const mapDispatchToProps = dispatch => {
        return {
            changeLanguage: (selected) => { dispatch(changeLanguageEn(selected))},
        };
    };

    const mapStateToProps = state => {
        return {
            language: state.language.selected,

        };
    };

    export default withNavigation(connect(
        mapStateToProps,
        mapDispatchToProps
    )(Account));

actions/Language.js

import {CHANGE_LANGUAGE_EN, CHANGE_LANGUAGE_AL} from "./types";

export const changeLanguageEn = (language) => {
    return {
        type: CHANGE_LANGUAGE_EN,
        lang: language,
    }
};

export const changeLanguageAl = (language) => {
    return {
        type: CHANGE_LANGUAGE_AL,
        lang: language,
    }
};

reducers/Language.js

const defaultState = {
    lang: '',
};

export default function reducer(state = defaultState, action) {
    switch (action.type) {
        case 'CHANGE_LANGUAGE_EN':
           return {...state, lang: 'en'};
        case 'CHANGE_LANGUAGE_AL':
            return Object.assign({}, state, {
                lang: 'sq',
            });
        default:
            return state;
    }
}
3
you get default state, that means you get lang:'' ? - McRist
@McRist yeah that's right - AnXD

3 Answers

1
votes

Not entirely sure I understand your question, but it sounds like you're trying to update the redux state with the internal state of Account? You should be able to do:

this.props.changeLanguage(this.state.language.selected)

You have a method on your component defined changeLanguage as well, perhaps you could do the line above in that method, after changing the internal state

additionally, in your changeLanguage method in your Account class, I don't think this.state.sq exists since sq is a key in the language state object. Instead it should be this.state.language.sq. You don't need to add the selected argument to this method either. Try making your changeLanguage method to look like this

changeLanguage = () => {
    if (this.state.sq) {
        this.setState({ language.selected: 'sq' });
    } else {
        this.setState({ language.selected: 'en' });
    }
   // dispatch your action here after updating the state
  this.props.changeLanguage(this.state.language.selected)
};

Now calling this.changeLanguage(); will update your internal state, and then dispatch your changeLanguage redux action

2
votes

In your mapStateToProps function try with state.lang directly

const mapStateToProps = state => {
    return {
        language: state.lang,
    };
};

Hope this will work.

1
votes

You are accessing the selected language incorrectly. state.language.selected.

In the reducer you are adding lang property in the state, so access it with the same property name in the mapStateToProps.

const mapStateToProps = state => {
    return {
        language: state.language.lang,
    };
};