My React Router thingy看起来像这样:
<Switch>
<Route path='/posts/:id' component={PostsView} />
<Route exact path='/' component={Home}/>
<Route component={NotFound}/>
</Switch>
我现在想要实现一个AudioPlayer并在同一页面上显示它。
我当然可以导入AudioPlayer
中的PostsView
并从那里渲染它。但是,我认为不混合两个组件会更好,更纯粹,但是在第三个组件中将它们放在另一个组件中,这三个组件都会呈现它们,并且只负责在屏幕上显示内容。
我试图这样做,但是我被卡住了,因为我的帖子组件需要路由/posts/:id
,所以我不能把它放在第三个组件中。我试过这样的事情:
<Switch>
<Route path='/sentences/:id' component={Main} />
<Route exact path='/' component={Home}/>
<Route component={NotFound}/>
</Switch>
然后在Main
我试过了:
render() {
return (
<div>
<PostsView />
<AudioPlayer />
</div>
);
}
...但这似乎是错误的方法,因为反应路由器出现了问题!结合这两个组件最合理的方法是什么,并保持我的路由完好无损?
答案 0 :(得分:0)
如果音频播放器是全局播放的,并且播放某些并且始终与应用中当前显示的内容无关,那么您可能需要考虑移动某些内容到像redux这样的全球商店。当您选择要播放的内容时,您可以通过操作更新redux
,在AudioPlayer
内,您可以监听商店中的更改并进行相应调整。
import { setCurrentlyPlaying } from "actions"
class SomeComponent extends React.Component {
onClickTrack = (track) => {
this.props.setCurrentlyPlaying(track)
}
}
export default connect(null, { setCurrentlyPlaying })(SomeComponent)
此随机组件通过redux设置当前播放的曲目 - 您还可以将操作调整为添加到播放列表等。
在audioplayer中
class AudioPlayer extends React.Component {
componentWillReceiveProps(nextProps) {
const nextTrack = nextProps.track
const currentTrack = this.props.track
if (nextTrack !== currentTrack) {
// do something
}
}
shouldComponentUpdate(nextProps) {
const nextTrack = nextProps.track
const currentTrack = this.props.track
if (nextTrack !== currentTrack) {
// do something
}
}
render() {
return (<audio src={this.props.track.src}/>)
}
}
export default connect(
(state) => {
return { track: state.currentlyPlaying }
}
)(AudioPlayer)
你可以通过多种方式做到这一点。我不确定audio
元素将如何对重新渲染做出反应(我自己从未使用过该元素),因此您可能必须实现shouldComponentUpdate
并确保不更新组件,除非你需要。
这样做,您将拥有一个全局“容器”,它将显示AudioPlayer
和React Router。
<div>
<Switch>...</Switch>
<AudioPlayer/>
</div>
编辑,如果您要么a)不介意传递回调以设置要播放的曲目并在共同的父级中维护此曲目,则不需要redux
。
class Parent extends React.Component {
state = { currentlyPlaying: null }
setCurrentlyPlaying = (track) => {
this.setState({ currentlyPlaying: track })
}
render() {
return (
<div>
<Child setCurrentlyPlaying={this.setCurrentlyPlaying}/>
<AudioPlayer currentlyPlaying={this.state.currentlyPlaying}/>
</div>
)
}
}
或b)使用context
提供回调 - 我不建议这样做,因为即使React的维护者建议不要使用上下文。我不熟悉上下文,所以如果你想这样做,你需要查看如何做。