I'm trying to read image file and upload it to jsonserver using fileReader API with React-Reduxtoolkit, everything is ok but there is warning when using useeffect without 'productInfo' and 'dispatch' dependencies, but when I add them into dependency array, it generate an infinite loop and I dont understand why ?
function CreProducts(props) {
debugger
const dispatch = useDispatch();
const productInfo = useSelector((state) => state.products.product);
const [url, seturl] = useState([]);
console.log(productInfo);
function handleChange(e) {
const { name, value } = e.target;
const file = e.target?.files && e.target.files;
// file handle.............................
if (file) {
const filelist = Array.from(file);
readFile(filelist);
return
} else {
dispatch(addProductInfo({ ...productInfo, [name]: value }));
}
}
// read file .........................
function readFile(files) {
for (let item of files) {
const reader = new FileReader();
reader.onload = function (e) {
let blob = e.target.result;
seturl((prev) => [...prev, blob]);
};
reader.readAsDataURL(item);
}
}
useEffect(() => {
if (url.length !== 0) {
dispatch(addProductInfo({ ...productInfo, 'pics': url }))
}
},[url, productInfo])
return(<>............</>)
After the initial setup of the component, the component renders then this is what is occurring:
render ->
^ useEffect ->
|____url.length > 0 -> dispatch() [[ Dependecy changes here - forces rerender ]]
| url.length === 0 ->
| handleChange ->
| readFile() ->
|__________setUrl [[ Dependency Changes here - forces rerender ]]
So you can see, once a change is detected, one or the other (either handleChange()
or useEffect()
always changes one of the depencecies - which causes the loop.
You don't need to change state in useEffect()
- dispatch the request in readFile
just after setUrl(). But you will need to dispatch with blob
rather than url
as it won't be available in state yet.