[英]State JSX component not updating
I have a audio component that uses a file picker and on it's onChange
event, the state is updated and the audio component is reloaded.我有一个使用文件选择器的音频组件,在它的onChange
事件中,更新了 state 并重新加载了音频组件。
fileLoaded = (event) => {
const url = URL.createObjectURL(event.target.files[0]);
let react_player = (
<AudioPlayer url={url} name={event.target.files[0].name} />
);
this.setState({ reactPlayer: react_player });
event.preventDefault();
};
render() {
return (
<div>
<form onSubmit={this.submitAudioFile}>
<Button
className="Button"
size="large"
variant="contained"
component="label"
startIcon={<CloudUploadIcon />}
>
Upload File
<input
accept="audio/*"
type="file"
onChange={this.fileLoaded}
style={{ display: "none" }}
/>
</Button>
</form>
{this.state.reactPlayer}
</div>
);
}
So every time the file is changed the reactPlayer
component is supposed to be re-rendered from the state.因此,每次更改文件时,都应该从 state 重新渲染reactPlayer
组件。 But that is not happening and the file loaded into reactPlayer
remains the same even after triggering the onChange
event.但这并没有发生,即使在触发onChange
事件后,加载到reactPlayer
中的文件也保持不变。
This is the AudioPlayer
component.这是AudioPlayer
组件。
constructor(props) {
super();
this.audioRef = React.createRef();
}
componentDidMount() {
this.setState({ audioSource: this.props.url, name: this.props.name });
console.log(this.props.name);
}
state = {
playing: false,
source: null,
currentTime: 0,
totalTime: 0,
audioSource: "",
name: "",
};
playOrPauseButton = () => {
// console.log("CALLED");
// const styleJson = { color: "#000", fontSize: "50" };
if (!this.state.playing) {
return (
<PlayCircleFilledIcon
// style={styleJson}
className="playPauseButtonHover"
onClick={this.playOrPause}
/>
);
} else {
return (
<PauseCircleFilledIcon
className="playPauseButtonHover"
// style={styleJson}
onClick={this.playOrPause}
/>
);
}
};
playOrPause = () => {
// console.log("Hello");
if (this.state.playing) {
this.audioRef.current.pause();
console.log("pause");
} else {
this.audioRef.current.play();
console.log("play");
}
const prevPlayingState = this.state.playing;
this.setState({ playing: !prevPlayingState });
};
audioIsPlaying = (e) => {
this.setState({ currentTime: Math.floor(e.target.currentTime) });
this.setState({ duration: Math.floor(e.target.duration) });
// console.log(this.state.currentTime + ":" + this.state.duration);
};
audioEnded = (e) => {
console.log("ended");
this.setState({ playing: false, currentTime: 0 });
};
audioWasLoaded = (e) => {
this.setState({ duration: Math.floor(e.target.duration) });
// let x = e.target.src;
};
render() {
let x = this.playOrPauseButton();
// this.getAudioLength();
return (
<div>
<LinearProgress
className="top"
variant="determinate"
value={(this.state.currentTime * 100) / this.state.duration}
/>
<div className={styles.audioPlayerDiv}>
{x}
<div>
<p style={{ textAlign: "center" }}>
{this.state.currentTime}/{this.state.duration}
</p>
<p style={{ fontWeight: "bold" }}>{this.state.name}</p>
</div>
<audio
onLoadedMetadata={(event) => this.audioWasLoaded(event)}
onEnded={(event) => this.audioEnded(event)}
onTimeUpdate={(event) => this.audioIsPlaying(event)}
src={this.state.audioSource}
ref={this.audioRef}
/>
<NoteAddIcon className="playPauseButtonHover"></NoteAddIcon>
{/* <button style={{ alignItems: "left" }}>take note</button> */}
</div>
</div>
);
}
}
export default AudioPlayer;```
Don't store jsx in state 不要在 state 中存储 jsx
Just store the url an name in state and render jsx.只需将 url 的名称存储在 state 中并渲染 jsx。
Like this像这样
...
state = {
url: '',
name: ''
}
fileLoaded = (event) => {
const url = URL.createObjectURL(event.target.files[0]);
let react_player = {
url,
name: event.target.files[0].name
};
this.setState({ reactPlayer: react_player });
event.preventDefault();
};
render() {
return (
<div>
<form onSubmit={this.submitAudioFile}>
<Button
className="Button"
size="large"
variant="contained"
component="label"
startIcon={<CloudUploadIcon />}
>
Upload File
<input
accept="audio/*"
type="file"
onChange={this.fileLoaded}
style={{ display: "none" }}
/>
</Button>
</form>
{/* {this.state.reactPlayer} */}
{this.state.url && <AudioPlayer url={this.state.url} name={this.state.name} />}
</div>
);
}
Found the solution to this.找到了解决方案。 The trick was to pass props and tampering with the state in the AudioPlayer
component.诀窍是传递道具并篡改AudioPlayer
组件中的 state。
<audio
onLoadedMetadata={(event) => this.audioWasLoaded(event)}
onEnded={(event) => this.audioEnded(event)}
onTimeUpdate={(event) => this.audioIsPlaying(event)}
src={this.props.url}
ref={this.audioRef}
/>
Just hooked up the src of audio tag to the prop that is passed from the parent component and everything came out fine.只需将音频标签的 src 连接到从父组件传递的道具,一切都很好。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.