我有一个音频组件从父母那里获取它的源URL。
export default class VideoPlayback extends Component {
constructor (props) {
super(props)
}
render () {
return (
<audio src={this.props.audioUrl} id="activeModuleAudio" style={{ width: '80%' }} autoPlay controls />
);
}
}
这一切都很好用,每次我传递音频组件一个新的URL,autoPlay开始播放新的音频。
问题在于,有时传递的URL与前一个URL相同,但我仍然需要自动播放“新”源(也与前一个源相同)。由于React没有看到任何更改,因此它不会更新组件,并且autoPlay不起作用。
有什么想法吗?
谢谢!
答案 0 :(得分:1)
强制更新组件您可以使用内置方法:this.forceUpdate()
重新渲染。方法还会跳过shouldComponentUpdate
,因此组件将始终重新呈现。
在你的情况下,我理解父组件是容器组件,因此获取数据并将其发送给子项,以避免向子项发送道具而不改变它但使用 immutable.js 创建新组件的问题或者只是按Object.assign
创建新对象。
因此,如果您的父组件具有此类代码(伪代码):
someData.audioUrl="newAudioUrl";
将其更改为:
someData=Object.assign({},someData,{audioUrl:"newAudioUrl"});
这个解决方案保证即使使用相同的网址,也会改变道具参考,因此子组件将在没有forceUpdate的情况下重新渲染。
答案 1 :(得分:0)
另一个选择是让React做它的事情,只是重置当组件接收道具时的当前时间。如果数据没有改变,为什么要重新渲染?
const audio = 'https://upload.wikimedia.org/wikipedia/commons/transcoded/b/bb/Test_ogg_mp3_48kbps.wav/Test_ogg_mp3_48kbps.wav.ogg';
class Player extends React.Component {
componentWillReceiveProps() {
this.refs.audio.currentTime = 0;
}
render() {
return <audio ref="audio" src={this.props.audio} autoPlay controls />;
}
}
class App extends React.Component {
constructor() {
super();
this.state = { audio }
}
passSameProps() {
this.setState({ audio });
}
render() {
return(
<div>
<button onClick={this.passSameProps.bind(this)}>Pass same props!</button>
<Player audio={this.state.audio} />
</div>
);
}
}
ReactDOM.render(<App/>, document.getElementById('View'));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>
<div id="View"></div>
↑音频自动播放警告!