简体   繁体   中英

where can i dispatch the action - redux?

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?

code

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM