I have a Functional style React Native component where I can happily call my Redux Action:
import * as React from 'react';
import {Text, View, StyleSheet, Dimensions} from 'react-native';
import MultiSlider from '@ptomasroos/react-native-multi-slider';
import {useSelector, useDispatch} from 'react-redux';
import {updateNumPosInCode} from './redux/actions/gameplayAction';
const width = Dimensions.get('window').width;
export default function Settings() {
const dispatch = useDispatch();
const numPosInCode = useSelector(store => store.gameplay.numPosInCode);
const handleNumPosInCodeUpdate = num => {
console.log(`handleNumPosInCodeUpdate: ${num}`);
dispatch(updateNumPosInCode(num));
};
return (
<View style={[styles.container]}>
<View>
<Text style={styles.text}>Number of Positions in the Code</Text>
<MultiSlider
sliderLength={width - 40}
values={[6]}
optionsArray={[4, 5, 6]}
snapped={true}
onValuesChangeFinish={handleNumPosInCodeUpdate.bind(this)}
/>
<Text style={styles.text}>{numPosInCode}</Text>
</View>
</View>
);
}
const styles = StyleSheet.create({
container: {
flexDirection: 'column',
flex: 1,
padding: 20,
justifyContent: 'space-evenly',
},
text: {
textAlignVertical: 'center',
textAlign: 'center',
},
});
However when I try to call the same action from this Class style React Native component, nothing happens. Can you spot my mistakes?
import * as React from 'react';
import {View, StyleSheet, Button} from 'react-native';
import {connect} from 'react-redux';
import {updateNumPosInCode} from './redux/actions/gameplayAction';
class ColourBoard extends React.Component {
constructor(props) {
super(props);
this.state = {
numPosInCode: 5,
};
}
render() {
return (
<View
style={[
styles.MainContainer,
{
top: this.state.top,
},
]}>
<Button
onClick={this.props.updateNumPosInCode(4)}
title="Test"
color="#841584"
/>
</View>
);
}
}
const mapStateToProps = state => ({
numPosInCode: state.numPosInCode,
});
// Actions:
const mapDispatchToProps = () => ({
updateNumPosInCode,
});
const styles = StyleSheet.create({
MainContainer: {
left: 1,
justifyContent: 'center',
alignItems: 'center',
height: '100%',
width: '100%',
position: 'absolute',
zIndex: 1,
},
});
export default connect(mapStateToProps, mapDispatchToProps())(ColourBoard);
CodePudding user response:
Yes. Your mapDispatchToProps
usage is wrong.
With connect
, there's two ways to use mapDispatch
:
- passing in an object full of action creators, in which case you get all the same functions as props but already wrapped up to dispatch actions when called
- passing in a function that gets
dispatch
as an argument, in which case it's up to you to do the wrapping
In this case, you're passing in the function form of mapDispatch
... **but you are only returning the plain action creators as the props, and not wrapping them to make use of dispatch
!
The simplest answer here is to change it to const mapDispatch = {updateNumPosInCode}
and pass that instead.
The better answer is to switch this to be a function component and make use of the useDispatch
hook instead.