I'm working on a music app, and I have a Purchase quota, that allows users to use the app.
So if a user plays 20 track music I will appear to him a modal or something.
So I have a component that's for play music "controller" name as <MusicPlayer/>
,
I add it in every screen I have music tracks there when user press to any track card I navigate them to screen that contains
so i want to do some counter when user playing a music increase it +1
so i don't know where can I make this dispatch, in MusicPlayer components?
or in every screen that contained this component and pass it as props?
actions/countPlayAction.js
import {SET_COUNT} from './types';
export const setCount = count => {
return {
type: SET_COUNT,
payload: count,
};
};
reducer/countPlayReducer.js
import {SET_COUNT} from '../actions/types';
let initial_state = {
count: 0,
};
const countPlayReducer = (state = initial_state, action) => {
switch (action.type) {
case SET_COUNT:
state = {
...state,
count: state.count + action.payload,
};
break;
}
return state;
};
export default countPlayReducer;
musicPlayer component
class MusicPlayer extends Component {
constructor(props) {
super(props);
this.state = {
tunes: props.tunes,
currentTrackIndex: props.currentTrackIndex,
rate: 1,
duration: 1,
currentTime: 0,
paused: true,
loading: true,
};
}
onLoad = data => {
this.setState({
duration: Math.floor(data.duration),
loading: false,
paused: true,
});
};
render() {
return (
<View>
<View>
<Video
ref={ref => {
this.player = ref;
}}
source={{
uri: this.state.tunes[this.state.currentTrackIndex].url,
}}
paused={this.state.paused}
playInBackground={true}
playWhenInactive={true}
onLoad={this.onLoad}
onProgress={this.onProgress.bind(this)}
onEnd={this.onEnd}
controls={false}
/>
<View style={styles.time}>
<View style={styles.timeChildView}>
<Text style={styles.timeChildViewText}>
{this.minutesAndSeconds(this.state.currentTime)}
</Text>
</View>
<View style={styles.timeChildView}>
<Text style={styles.timeChildViewText}>
{this.minutesAndSeconds(this.state.duration)}
</Text>
</View>
</View>
<View style={styles.slider}>
{/* For circle play */}
<Slider
thumbTintColor="#ff4865"
maximumTrackTintColor="grey"
minimumTrackTintColor="#ff4865"
style={styles.seekBar}
step={1}
minimumValue={0}
maximumValue={this.state.duration}
value={this.state.currentTime}
onValueChange={this.changeValue}
onSlidingComplete={this.onSlidingComplete}
/>
</View>
<View style={styles.controls}>
{this.state.loading ? (
<ActivityIndicator size="large" color="#ff4865" />
) : (
<View style={styles.flexRow}>
<View>
{!this.state.paused ? (
<Button
transparent
style={styles.btnSection}
color="white"
onPress={() =>
this.setState({paused: !this.state.paused})
}>
<Icon name="md-pause" style={styles.iconColor} />
</Button>
) : (
<Button
transparent
style={styles.btnSection}
color="white"
onPress={() =>
this.setState({paused: !this.state.paused})
}>
<Icon name="md-play" style={styles.iconColor} />
</Button>
)}
</View>
</View>
)}
</View>
</View>
</View>
);
}
}
export default MusicPlayer;
What I made, it's increase count +1 in every time i play a track, but i don't know if that's a right way or not
in music player component
onLoad = data => {
this.setState({
duration: Math.floor(data.duration),
loading: false,
paused: true,
});
this.props.setCount(1)
reactotron.log(store.getState());
};
const mapDispatchToProps = dispatch => {
return {
setCount: count => {
dispatch(setCount(count));
},
};
};
// export default MusicPlayer;
export default connect(null, mapDispatchToProps)(MusicPlayer);
It looks logically done, although have a feeling of overhead introduced by redux (that's usual on small scale apps). I would also advice to change setCount
to incrementCount
, so that you don't need to have an absolute value in the component which increases the value.
You followed the Component-Container principle, what is not bad, but in your case you don't get any data from mapStateToProps
and it forced you to have some boilerplate code inside of mapDispatchToProps
.
An idea how to simplify it - you can wrap your component with connect
and then you'll have dispatch
available under props
object inside of your component, so that you can immediately dispatch the action from onLoad
. It will look like this:
onLoad = data => {
this.props.dispatch(setCount(1));
};
Final couple of words, if you don't have any other use cases for redux have a look at React.Context as you'll have less boilerplate with it :)
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.