Reputation: 409
i have a simple state and a function that runs in useEffect, i setup the useEffect second argument to my updating state but seems to run in an endless loop causing endless re-renders
const [file, setFile] = useState({audioFile: {} })
const loadAudioFromPath = (path) => {
import(`../components/Media/Resources/${path}`).then(audio =>
setFile({
audioFile: new Audio(audio),
})
);
}
useEffect(() => {
loadAudioFromPath(resourceURI)
console.log(file)
}, [file])
i also tried
useEffect(() => {
loadAudioFromPath(resourceURI)
console.log(file)
}, [])
still same issue!
Upvotes: 0
Views: 85
Reputation: 2243
This is happeing because you are watching for file changes, and you are making changes in file using setFile inside of useEffect, so you made the loop.
So to help you more, i need to know what you really is trying to achivie with that file.
1 - If you trying to just load the file once it is uploaded you can try something like:
const { file, setFile } = useState();
const { resourceURI, setResourceURI } = useState();
useEffect(() => {
loadAudioFromPath(resourceURI)
}, [resourceURI])
const loadAudioFromPath = (path) => {
import(`../components/Media/Resources/${path}`).then(audio =>
setFile({
audioFile: new Audio(audio),
})
);
}
2 - If you trying to load the file just once (when the page is mounted)(Will do nothing if you change the file):
const { file, setFile } = useState();
useEffect(() => {
loadAudioFromPath(resourceURI);
}, [])
const loadAudioFromPath = (path) => {
import(`../components/Media/Resources/${path}`).then(audio =>
setFile({
audioFile: new Audio(audio),
})
);
}
3 - Or if you want to load the file if the current file is diferent than last one you can do something like i did in that answer -> A property is undefined - switching from class components to function hooks components in React
Upvotes: 0
Reputation: 409
inspired by dr.Telma i fixed it by putting the result of the promise in a separate state then using that to create a new Audio and set it in the other state
const [file, setFile] = useState({audioFile: {} })
const [comp, setComp] = useState({audioComp: {} })
useEffect(() => {
import(`../components/Media/Resources/${resourceURI}`).then(audio =>
setComp({
audioComp: audio.default,
})
).then(()=>
setFile({
audioFile: new Audio(comp.audioComp),
})
)
}, [])
Upvotes: 0
Reputation: 129
There must be some other issue in the code as:
useEffect(() => { loadAudioFromPath(resourceURI) console.log(file) }, [])
will only render once when the component loads. Happy to look into the rest of the code, if you add some more texture to the problem.
Upvotes: 0
Reputation: 3196
EDIT: Try and change your useEffect
to something like this:
Basically, add a boolean. If the boolean state changes then useEffect will fire.
const [file, setFile] = useState({audioFile: {} })
const [bool, setBool] = useState(false)
const loadAudioFromPath = (path) => {
import(`../components/Media/Resources/${path}`).then(audio =>
setFile({
audioFile: new Audio(audio),
})
if (file.length !== 0) {
setBool(true)
}
);
}
useEffect(() => {
loadAudioFromPath(resourceURI)
console.log(file)
}, [bool])
Upvotes: 1
Reputation: 1534
useEffect(() => {
loadAudioFromPath(resourceURI)
console.log(file)
}, [])
Upvotes: 0