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.
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. But that is not happening and the file loaded into reactPlayer
remains the same even after triggering the onChange
event.
This is the AudioPlayer
component.
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;```
Just store the url an name in state and render 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>
);
}