这是我遇到的问题。我必须将id={this.props.id}
传递给每个组件,这样我才能通过查看ownProps从mapStateToProps
中的玩家列表中获取正确的玩家。
我的问题是:
如何从列表中获取正确的播放器,而无需将ID传递给我的每个组件,如下面的代码所示?
如果mapStateToProps
接受context
param,那么我可以从每个组件的上下文中获取id并将其传递一次。
他们是更好的方法吗?
开发人员定义的AudioPlayers:
class AudioPlayer extends React.Component {
render() {
return (
<Player className="jp-default" id={this.props.id}>
<Gui id={this.props.id}>
<Media id={this.props.id}>
<Audio id={this.props.id}>
</Audio>
</Media>
<div className="poster-container">
<Poster id={this.props.id}/>
<Title id={this.props.id}/>
</div>
</Gui>
</Player>
);
}
}
AudioPlayer.options = {
id: "audio-player",
paused: true,
//...etc
};
class AudioPlayerTwo extends React.Component {
render() {
return (
<Player className="jp-default-two" id={this.props.id}>
<Gui id={this.props.id}>
<Media id={this.props.id}>
<Audio id={this.props.id}>
</Audio>
</Media>
<div className="poster-container">
<Poster id={this.props.id}/>
<Title id={this.props.id}/>
</div>
</Gui>
</Player>
);
}
}
AudioPlayerTwo.options = {
id: "audio-player-two,
paused: true,
//...etc
};
createPlayers([AudioPlayer, AudioPlayerTwo]);
将成为npm包的代码:
export createPlayers (WrappedPlayers) => {
const store = createStore(combineReducers({players: playerReducer}));
ReactDOM.render(
<Provider store={store}>
<div>
{WrappedPlayers.map(WrappedPlayer => {
const ConnectedPlayer = connect(mapStateToProps, mapDispatchToProps)(WrappedPlayer);
<ConnectedPlayer key={WrappedPlayer.options.id} id={WrappedPlayer.options.id} />
})}
</div>
</Provider>,
document.getElementById("app"));
}
动作:
export const play = (id, time) => ({
type: actionTypes.player.PLAY,
time,
id
});
...etc
减速器:
const play = (state, action) => {
if(state.srcSet) {
return updateObject(state, {
paused: false,
newTime: !isNaN(action.time) ? action.time : state.currentTime
});
}
}
export default (state={}, action) => {
//Only update the correct player
const currentPlayer = state[action.id];
let newState = {...state};
switch (action.type) {;
case actionTypes.player.PLAY:
newState = play(currentPlayer, action);
break;
default:
return state;
}
return updateObject(state, {
[action.id]: newState
});
}
我的所有组件都与此类似:
请注意我如何使用道具id
从列表中访问正确的播放器。
const mapStateToProps = (state, props) => ({
paused: state.players[props.id].paused,
id: props.id
});
const Play = (props) => {
const onPlayClick = () => props.paused ? props.dispatch(play(props.id)) : props.dispatch(pause(props.id))
return <a onClick={onPlayClick}>{props.children}</a>
}
export default connect(mapStateToProps)(Play);
答案 0 :(得分:4)
您可以通过在connect
+ getContext
(来自recompose)上创建自己的包装来在userland中解决此问题,并在您的应用中使用它而不是vanilla connect。它看起来像
import { connect } from 'react-redux'
import { compose, getContext } from 'recompose'
export default function connectWithMyId(...args) {
return compose(
getContext({ myId: PropTypes.string }),
connect(...args)
)
}
然后myId
将mapStateToProps
作为道具提供。{/ 1}}。