Reputation: 340
I use Redux to set three Counters for my navigation bar. I can access the values in initial state. But I am unable to change the values. My Reducer looks like this:
const SET_FREUNDE = 'SET_FREUNDE';
const SET_CHATS = 'SET_CHATS';
const SET_VOTES = 'SET_VOTES';
export function setFreunde(value) {
return {
type: SET_FREUNDE,
value,
}
}
export function setChats(value) {
return {
type: SET_CHATS,
value,
}
}
export function setVotes(value) {
return {
type: SET_VOTES,
value,
}
}
const defaults =
{
countervotes: 2,
counterchats: 1,
counterfreunde: 1
};
function counter(state=defaults, action) {
switch (action.type) {
case SET_FREUNDE:
return {...state,counterfreunde: action.value}
case SET_CHATS:
return {...state,counterchats: action.value}
case SET_VOTES:
return {...state,countervotes: action.value}
default:{
return state;
}
}
}
export default counter;
Now I want to set the counters on a other screen:
import * as React from "react";
import { Image, StyleSheet,... } from "react-native";
...
import {connect} from 'react-redux';
import { setChats, setFreunde, setVotes } from '../redux/counter';
class ... extends React.Component<{}, State> {
constructor(props) {
super(props);
}
...
render(){
return(
<SafeAreaView style={styles.container}>
<Button onPress={() => setFreunde(2)}/>
...
</SafeAreaView>
);
}
}
const styles = StyleSheet.create({
...
});
const mapDispatchToProps = (dispatch, ownProps) => ({
setFreunde: () => {
const { value } = ownProps
dispatch(setFreunde(value))
},
setChats: () => {
const { value } = ownProps
dispatch(setChats(value))
},
setVotes: () => {
const { value } = ownProps
dispatch(setVotes(value))
}
})
export default connect( null, mapDispatchToProps )(NavStack)
If I log the setFreunde(2) the console says the following:
Object { "type": "SET_FREUNDE", "value": 2, }
However, the value does not change which I retrieve in my App.tsx as follows:
const counterfreunde = useSelector((state)=>state.counterfreunde);
What is my mistake?
Upvotes: 0
Views: 117
Reputation: 42160
<Button onPress={() => setFreunde(2)}/>
This code right here is just calling the action creator setFreunde
. It does not dispatch
it.
Your mapDispatchToProps
function adds a prop setFreunde
to your component which takes no arguments and dispatches the action with the value from props.value
. You are not using this prop. You are just using the action creator. You need to call the function from props:
<Button onPress={this.props.setFreunde} title="Set Freunde" />
That fixes the functionality. You do need to add a lot of annotations if you are trying to use typescript here. It's easier with function components!
import { createStore } from "redux";
import { Provider, connect } from "react-redux";
import React, { Dispatch } from "react";
import { SafeAreaView, Button, Text } from "react-native";
const SET_FREUNDE = "SET_FREUNDE";
const SET_CHATS = "SET_CHATS";
const SET_VOTES = "SET_VOTES";
export function setFreunde(value: number) {
return {
type: SET_FREUNDE,
value
};
}
export function setChats(value: number) {
return {
type: SET_CHATS,
value
};
}
export function setVotes(value: number) {
return {
type: SET_VOTES,
value
};
}
const defaults = {
countervotes: 2,
counterchats: 1,
counterfreunde: 1
};
type State = typeof defaults;
type Action = ReturnType<typeof setVotes | typeof setChats | typeof setFreunde>;
function counter(state: State = defaults, action: Action): State {
switch (action.type) {
case SET_FREUNDE:
return { ...state, counterfreunde: action.value };
case SET_CHATS:
return { ...state, counterchats: action.value };
case SET_VOTES:
return { ...state, countervotes: action.value };
default: {
return state;
}
}
}
const store = createStore(counter);
const mapDispatchToProps = (
dispatch: Dispatch<Action>,
ownProps: OwnProps
) => ({
setFreunde: () => {
const { value } = ownProps;
dispatch(setFreunde(value));
},
setChats: () => {
const { value } = ownProps;
dispatch(setChats(value));
},
setVotes: () => {
const { value } = ownProps;
dispatch(setVotes(value));
}
});
const mapStateToProps = (state: State) => ({
freund: state.counterfreunde
});
interface OwnProps {
value: number;
}
type Props = OwnProps &
ReturnType<typeof mapDispatchToProps> &
ReturnType<typeof mapStateToProps>;
class NavStack extends React.Component<Props> {
render() {
return (
<SafeAreaView>
<Text>Freunde Value: {this.props.freund}</Text>
<Button onPress={this.props.setFreunde} title="Set Freunde" />
</SafeAreaView>
);
}
}
const Test = connect(mapStateToProps, mapDispatchToProps)(NavStack);
export default function App() {
return (
<Provider store={store}>
<Test value={5} />
</Provider>
);
}
Upvotes: 1