I have a React app, where I have this method
const fetchPons = () => {
fetch('http://localhost:8080/pons/')
.then(r => r.json())
.then(resp => {
if (resp.ok === true) {
setPons(resp.pons);
} else {
setErrors(resp.errors);
}
})
.catch(e => console.log(e));
};
And am trying to use it in useEffect
like this:
useEffect(() => {
fetchPons().catch(e => console.log(e));
}, []);
but get
TypeError: fetchPons(...) is undefined
Here's the full code, since I have no idea what can be useful
import React, {useState, useEffect} from 'react';
import './App.css';
import {PonCard} from "./components/PonCard";
import {EnterEditModeButton, ExitEditModeButton} from "./components/buttons/EditButtons";
import {SaveTranslationsButton} from "./components/buttons/SaveTranslationsButton";
import {CancelButton} from "./components/buttons/CancelButton";
import {TranslationsTable} from "./components/TranslationsTable";
import {InputField} from "./components/InputField";
import {TranslateButton} from "./components/buttons/TranslateButton";
function App() {
const [pons, setPons] = useState();
const [translations, setTranslations] = useState();
const [isInEditMode, setIsInEditMode] = useState(false);
const [inputValue, setInputValue] = useState('');
const [errors, setErrors] = useState([]);
const [translationsToSave, setTranslationsToSave] = useState([]);
const [ponSelectedForEdit, setPonSelectedForEdit] = useState(null);
const [isInTranslationMode, setIsInTranslationMode] = useState(false);
const generateFetchParams = (method, body) => ({
method,
body,
mode: 'cors',
headers: {
'Content-Type': 'application/json',
}
});
const handleInputChange = (e) => setInputValue(e.target.value);
const fetchTranslations = async (e, value = inputValue) => {
const resp = await fetch(`http://localhost:8080/pons/findTranslation/${value}`)
.then(r => r.json())
.catch(e => console.log(e));
if (resp.ok === true) {
setTranslations(resp.resp[0].hits);
setErrors([]);
} else {
setErrors(resp.errors ? resp.errors : ['Something went wrong. check the input']);
}
};
const handleSaveTranslations = async () => {
if (isInEditMode) {
const resp = await fetch(`http://localhost:8080/pons/${ponSelectedForEdit._id}`,
generateFetchParams('PUT', JSON.stringify({translations: translationsToSave}))).then(r => r.json())
.catch(e => {
console.log(e);
return {ok: false};
});
if (resp.errors) {
setErrors(resp.errors);
}
} else {
const resp = await fetch('http://localhost:8080/pons/',
generateFetchParams('PUT', JSON.stringify({
original: inputValue,
translations: translationsToSave
}))).then(r => r.json())
.then(r => r.json())
.catch(e => {
console.log(e);
return {ok: false};
});
if (resp.errors) {
setErrors(resp.errors);
}
}
setInputValue('');
setTranslations(null);
setIsInEditMode(false);
await fetchPons();
};
const fetchPons = () => {
fetch('http://localhost:8080/pons/')
.then(r => r.json())
.then(resp => {
if (resp.ok === true) {
setPons(resp.pons);
} else {
setErrors(resp.errors);
}
})
.catch(e => console.log(e));
};
const handleDeletingPon = async (id) => {
const resp = await fetch(`http://localhost:8080/pons/${id}`, generateFetchParams('DELETE'))
.then(r => r.json())
.catch(e => {
console.log(e);
return {ok: false};
});
if (resp.ok) {
setPons((prev) => {
const index = prev.findIndex(elem => elem._id === id);
return [...prev.slice(0, index), ...prev.slice(index + 1)]
})
}
if (resp.errors) {
setErrors(resp.errors);
}
};
useEffect(() => {
fetchPons().catch(e => console.log(e));
}, []);
useEffect(() => {
if (ponSelectedForEdit !== null) {
const {original, translations} = ponSelectedForEdit;
setInputValue(original);
fetchTranslations(null, original).then(() => {
translations.forEach(translation => setTranslationsToSave(prev => [...new Set([...prev, translation])]));
}).catch(e => console.log(e));
}
}, [ponSelectedForEdit]);
useEffect(() => {
setTranslationsToSave([]);
}, [inputValue]);
return (
<div className="App">
<InputField {...{handleInputChange, inputValue, isInEditMode, setInputValue,}}/>
<div className="mb-3">
<TranslateButton {...{inputValue, errors, isInEditMode, fetchTranslations, setIsInTranslationMode}}/>
{
!isInEditMode ? (
<EnterEditModeButton {...{setIsInTranslationMode, setTranslations, setIsInEditMode}}/>
) : (
<ExitEditModeButton {...{
isInTranslationMode,
setIsInEditMode,
setPonSelectedForEdit,
setTranslations,
setInputValue,
}} />
)
}
<SaveTranslationsButton {...{translationsToSave, handleSaveTranslations, setIsInTranslationMode,}}/>
{
isInTranslationMode ? (
<CancelButton {...{setIsInTranslationMode, setTranslations, setInputValue,}}/>
) : null
}
</div>
{errors.length > 0 ? errors.map(e => <div key={e}>{e}</div>) : null}
{
pons && !translations && inputValue === '' ? pons.map(pon => (
<PonCard key={Math.random()} {...{pon, isInEditMode, setPonSelectedForEdit, handleDeletingPon}}/>
)) : null
}
{
translations ?
<TranslationsTable {...{translations, translationsToSave, setTranslationsToSave}}/>
: null
}
</div>
);
}
export default App;
Why does this happen and how do I fix this?
Full error:
TypeError: fetchPons(...) is undefined
App/<
C:/Users/aironsid/Documents/Capgemini/NodeJsCourseTask/server/views/src/App.js:108
105 | };
106 |
107 | useEffect(() => {
> 108 | fetchPons().catch(e => console.log(e));
109 | }, []);
110 |
111 | useEffect(() => {
I fixed it by changing fetchPons
to
const fetchPons = () => fetch('http://localhost:8080/pons/')
.then(r => r.json())
.then(resp => {
if (resp.ok === true) {
setPons(resp.pons);
} else {
setErrors(resp.errors);
}
})
.catch(e => console.log(e));
But why? Why does it have to return the fetch function?