admin管理员组文章数量:1404567
What would be the ideal way to manage a video player using Redux, primarily in terms of dispatching actions to play/pause a video?
I'm working on building a video player in a React application, and I have event listeners on the video player dispatching relevant events to update the state. What would be the best way to have the parent ponent act on other ponents dispatching a PLAY or PAUSE action?
One use case that I would want to account for, for example, is one video being played and all other videos making sure to pause their playback.
Two ways that I've thought of would be:
1) Have the parent ponent check for changes in ponentWillReceiveProps
, and checking for something like
if (this.props.paused && !nextProps.paused) {
this.refs.video.play()
}
2) Store a reference to the underlying video element in the state tree, and using middleware to act on certain actions (such as a PLAY
action), such as
if (action.type === PLAY) {
let state = getState();
state.players[action.payload.playerId].play();
}
Would one strategy be more "correct" than the other, or is there another way that would make more sense?
What would be the ideal way to manage a video player using Redux, primarily in terms of dispatching actions to play/pause a video?
I'm working on building a video player in a React application, and I have event listeners on the video player dispatching relevant events to update the state. What would be the best way to have the parent ponent act on other ponents dispatching a PLAY or PAUSE action?
One use case that I would want to account for, for example, is one video being played and all other videos making sure to pause their playback.
Two ways that I've thought of would be:
1) Have the parent ponent check for changes in ponentWillReceiveProps
, and checking for something like
if (this.props.paused && !nextProps.paused) {
this.refs.video.play()
}
2) Store a reference to the underlying video element in the state tree, and using middleware to act on certain actions (such as a PLAY
action), such as
if (action.type === PLAY) {
let state = getState();
state.players[action.payload.playerId].play();
}
Would one strategy be more "correct" than the other, or is there another way that would make more sense?
Share Improve this question asked Mar 9, 2016 at 18:06 Andrew BurgessAndrew Burgess 5,2965 gold badges33 silver badges37 bronze badges 1- Did you ever find a solution that was satisfactory for your needs? Have any examples of this implemented? – Joshua F. Rountree Commented Jun 4, 2018 at 12:01
3 Answers
Reset to default 31) is the way to go.
Your video is simply a view ponent. In React you always want the ponent's props to dictate the output.
The problem with 2) is that the video object doesn't belong in the state. You're telling Redux too much about the implementation detail. Redux doesn't care about the implementation detail; it's just a state container.
UPDATE
On further reflection, I remend ponentDidUpdate()
is the best place to place this logic. i.e.
ponentDidUpdate(prevProps)
if (prevProps.paused && !this.props.paused) {
this.refs.video.play();
}
}
The advantage being that ponentDidUpdate()
is called after re-rendering. It may not make a difference for your purposes, but it's possible that triggering a DOM event before React has had a chance to update the DOM may cause some unfortunate race conditions.
Of course this doesn't change the gist of my advice that output should always be props (or state) driven.
I don't think that you need (2), (1) is pretty good. Now you handle only play action, but you can add pause there, like this:
if (this.props.paused && !nextProps.paused) {
this.refs.video.play()
}
if (!this.props.paused && nextProps.paused) {
this.refs.video.pause()
}
In this case your html player state will be synchronized with redux player state.
One use case that I would want to account for, for example, is one video being played and all other videos making sure to pause their playback.
In this case you can handle this situation in your reducer. I'd store all players by ids with paused state, like:
{
1: {
paused: true,
},
2: {
paused: false,
},
...
}
You need to add player id in your action and pause other players, when you receive PLAY
action:
function players(state = {}, action) {
switch (action.type) {
case PAUSE:
return {
...state,
[action.id]: {
paused: true
}
}
case PLAY:
const nowPlaying = Object.keys(state).find(id => !state[id].paused);
const newState = {
...state,
[action.id]: {
paused: false
}
};
if (nowPlaying) {
newState[nowPlaying].paused = true;
}
return newState;
}
}
import { createSlice } from '@reduxjs/toolkit';
const initialState = {};
const playersSlice = createSlice({
name: 'players',
initialState,
reducers: {
pausePlayer(state, action) {
const playerId = action.payload;
state[playerId].paused = true;
},
playPlayer(state, action) {
const playerId = action.payload;
const previouslyPlaying = Object.entries(state).find(([id, player]) => !player.paused);
state[playerId].paused = false;
// Pause previously playing player only if it exists and isn't the same player
if (previouslyPlaying && previouslyPlaying[0] !== playerId) {
state[previouslyPlaying[0]].paused = true;
}
},
},
});
export const { pausePlayer, playPlayer } = playersSlice.actions;
export default playersSlice.reducer;
本文标签: javascriptUsing Redux to Manage a Video PlayerStack Overflow
版权声明:本文标题:javascript - Using Redux to Manage a Video Player - Stack Overflow 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.betaflare.com/web/1744829604a2627271.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论