react why is setCategories is not defined error

Hello, For wordpress im busy with making a component who reads all categories. So far I have this :
const [categories, setCategories] = useState([]);
const [chosenCategory, setChosenCategory] = useState(0)
const [posts, setPosts] = useState([]);

useEffect(() => {
async function fetchCategories() {

const queryParams = { _fields: ['name', 'id'] };
apiFetch({ path: addQueryArgs('/wp/v2/categories', queryParams) }).then((response) => {
setCategories(response).catch((error) => {console.log(error)});
});

}
fetchCategories();
}, []);
const [categories, setCategories] = useState([]);
const [chosenCategory, setChosenCategory] = useState(0)
const [posts, setPosts] = useState([]);

useEffect(() => {
async function fetchCategories() {

const queryParams = { _fields: ['name', 'id'] };
apiFetch({ path: addQueryArgs('/wp/v2/categories', queryParams) }).then((response) => {
setCategories(response).catch((error) => {console.log(error)});
});

}
fetchCategories();
}, []);
but when I run this I see a message that setCategories is undefined. Can someone explain why this happens and how to solve it
69 Replies
glutonium
glutoniumā€¢3mo ago
if the function is an async function then why r u not using await
async function fetchCategories() {
const queryParams = { _fields: ['name', 'id'] };
try{
const response = await apiFetch({ path: addQueryArgs('/wp/v2/categories', queryParams)
await setCategories(response);
}
catch(err){ console.log(err) }
}
async function fetchCategories() {
const queryParams = { _fields: ['name', 'id'] };
try{
const response = await apiFetch({ path: addQueryArgs('/wp/v2/categories', queryParams)
await setCategories(response);
}
catch(err){ console.log(err) }
}
shoudn't it be like this? also u have catch block chained to the setCategories i should be chained to the then()
then(() => {
// callback fn
})
.catch()
then(() => {
// callback fn
})
.catch()
roelof
roelofā€¢3mo ago
tried that and it was not working
glutonium
glutoniumā€¢3mo ago
show da error dis dont work either?
roelof
roelofā€¢3mo ago
nope, still no difference and with the latest code I do not see any error I see only that the categories stays empty
glutonium
glutoniumā€¢3mo ago
what is your latest code
roelof
roelofā€¢3mo ago
const [categories, setCategories] = useState([]);

const [chosenCategory, setChosenCategory] = useState(0);

const [posts, setPosts] = useState([]);

useEffect(() => {

async function fetchCategories() {

const queryParams = { _fields: ['name', 'id'] };

try {

const response = await apiFetch({ path: addQueryArgs('/wp/v2/categories', queryParams) });

setCategories(response);
console.log(categories);

} catch (error) {

console.log(error);

}

}

fetchCategories();

}, []);

const [categories, setCategories] = useState([]);

const [chosenCategory, setChosenCategory] = useState(0);

const [posts, setPosts] = useState([]);

useEffect(() => {

async function fetchCategories() {

const queryParams = { _fields: ['name', 'id'] };

try {

const response = await apiFetch({ path: addQueryArgs('/wp/v2/categories', queryParams) });

setCategories(response);
console.log(categories);

} catch (error) {

console.log(error);

}

}

fetchCategories();

}, []);

but also with your code the dropdown stays empty
glutonium
glutoniumā€¢3mo ago
what if u do something like this does it show up as empty on the page or r u saying cause the console.log logs out empty array maybw try like this
const [categories, setCategories] = useState([]);

const [chosenCategory, setChosenCategory] = useState(0);

const [posts, setPosts] = useState([]);

useEffect(() => {

async function fetchCategories() {
const response = [];
const queryParams = { _fields: ['name', 'id'] };

try {

response = await apiFetch({ path: addQueryArgs('/wp/v2/categories', queryParams) });

console.log(categories);

} catch (error) {

console.log(error);

}
return response;
}

setCategories(fetchCategories());

}, []);

const [categories, setCategories] = useState([]);

const [chosenCategory, setChosenCategory] = useState(0);

const [posts, setPosts] = useState([]);

useEffect(() => {

async function fetchCategories() {
const response = [];
const queryParams = { _fields: ['name', 'id'] };

try {

response = await apiFetch({ path: addQueryArgs('/wp/v2/categories', queryParams) });

console.log(categories);

} catch (error) {

console.log(error);

}
return response;
}

setCategories(fetchCategories());

}, []);

roelof
roelofā€¢3mo ago
no luck
TypeError: invalid assignment to const 'response'
TypeError: invalid assignment to const 'response'
glutonium
glutoniumā€¢3mo ago
j updated the code change the const to let if doesn't work then try with updated code
roelof
roelofā€¢3mo ago
the updated code gives also this :

TypeError: invalid assignment to const 'response'
fetchCategories edit.js:55
Edit edit.js:67
Ur react-dom.min.js:10
El react-dom.min.js:10
fl react-dom.min.js:10
Nn react-dom.min.js:10
xl react-dom.min.js:10
xl react-dom.min.js:10
ol react-dom.min.js:10
v react.min.js:10
ce react.min.js:10
t react.min.js:10
<anonymous> react.min.js:10
<anonymous> react.min.js:10

TypeError: invalid assignment to const 'response'
fetchCategories edit.js:55
Edit edit.js:67
Ur react-dom.min.js:10
El react-dom.min.js:10
fl react-dom.min.js:10
Nn react-dom.min.js:10
xl react-dom.min.js:10
xl react-dom.min.js:10
ol react-dom.min.js:10
v react.min.js:10
ce react.min.js:10
t react.min.js:10
<anonymous> react.min.js:10
<anonymous> react.min.js:10
glutonium
glutoniumā€¢3mo ago
dis u change the const response to let response? i this is a common error u should be able to solve your own
roelof
roelofā€¢3mo ago
no luck no error message but also no dropdown anymore at the side
glutonium
glutoniumā€¢3mo ago
welp.. can't tell then make sure your api is actually returning a response
roelof
roelofā€¢3mo ago
No description
glutonium
glutoniumā€¢3mo ago
console.log tbe response within the try block
roelof
roelofā€¢3mo ago
I know that it does
glutonium
glutoniumā€¢3mo ago
do this make sure to console after the response = awat ...
roelof
roelofā€¢3mo ago
response :

0: Object { id: 1, name: "Niet gecategoriseerd" }
ā€‹
length: 1
ā€‹
<prototype>: Array []

0: Object { id: 1, name: "Niet gecategoriseerd" }
ā€‹
length: 1
ā€‹
<prototype>: Array []
and that is what I expect
glutonium
glutoniumā€¢3mo ago
is tbis what what shows up in dda console?
roelof
roelofā€¢3mo ago
yep and the categories is still a empty array very very wierd
glutonium
glutoniumā€¢3mo ago
can u show a screenshot pls? of the console
roelof
roelofā€¢3mo ago
No description
roelof
roelofā€¢3mo ago
you are offline but still answered me
glutonium
glutoniumā€¢3mo ago
what's the 2nd console? Array [] length: 0
roelof
roelofā€¢3mo ago
the categories
glutonium
glutoniumā€¢3mo ago
u can set your status offline in discord hmm r u accessing these elements properly?
roelof
roelofā€¢3mo ago
yep this is annpying me for several days now as far as I know I do accessing things well most wierd is if I put a map between it where I make a array of the same content , everything works well
glutonium
glutoniumā€¢3mo ago
ok instead of setCategories (fetchCategories()) try doing setCategories( preCategories => preCategories = Array.from(fetchCategories())) also console.log preCategories here
roelof
roelofā€¢3mo ago
sorry, I do not see how to log preCategories here but now in the console no errors but also no dropdown in the sidebar šŸ˜¦ but categories stays a empty array very very annoying problem
glutonium
glutoniumā€¢3mo ago
weird idk man . I'm out of ideas sorry
roelof
roelofā€¢3mo ago
no problem Thanks for trying to help me
glutonium
glutoniumā€¢3mo ago
welcome
missymae#2783
missymae#2783ā€¢3mo ago
In the example code, inside the useEffect
setCategories(response);
console.log(categories);
setCategories(response);
console.log(categories);
the console.log() should return empty array because of React batch updates. Even though categories is logged after the setter call, categories will return the previous state because it is in the same functional call (the same useEffect); even if you use a callback like setTimeout. So if you expect to see the dropdown set in that useEffect, it could be a problem. In that case, you can add another useEffect with [categories] as the dependency, and set your dropdown inside.
roelof
roelofā€¢3mo ago
hmm, or I do misunderstood you But this is also causing the drop down to be empty :
const [categories, setCategories] = useState([]);

useEffect(() => {

async function fetchCategories() {

const queryParams = { _fields: ['name', 'id'] };

try {

const response = await apiFetch({ path: addQueryArgs('/wp/v2/categories', queryParams) });

setCategories(response);
console.log(categories);

} catch (error) {

console.log(error);

}

}

fetchCategories();

}, [categories]);


<SelectControl
label="Choose Category"
value={chosenCategory}
options={categories}
onChange={(category) => setChosenCategory(category)}
/>
const [categories, setCategories] = useState([]);

useEffect(() => {

async function fetchCategories() {

const queryParams = { _fields: ['name', 'id'] };

try {

const response = await apiFetch({ path: addQueryArgs('/wp/v2/categories', queryParams) });

setCategories(response);
console.log(categories);

} catch (error) {

console.log(error);

}

}

fetchCategories();

}, [categories]);


<SelectControl
label="Choose Category"
value={chosenCategory}
options={categories}
onChange={(category) => setChosenCategory(category)}
/>
@missymae#2783
missymae#2783
missymae#2783ā€¢3mo ago
seeing the SelectControl element using options={categories}, I don't think the useEffect issue I described earlier is a problem.
roelof
roelofā€¢3mo ago
hmm, when I do what you said I see this :
No description
roelof
roelofā€¢3mo ago
sory here a better one :
No description
roelof
roelofā€¢3mo ago
@missymae#2783
SyntaxError: C:\laragon\www\learn\wp-content\plugins\rw-filter-categories\src\edit.js: Unexpected reserved word 'await'. (68:4)
SyntaxError: C:\laragon\www\learn\wp-content\plugins\rw-filter-categories\src\edit.js: Unexpected reserved word 'await'. (68:4)
missymae#2783
missymae#2783ā€¢3mo ago
oof, my mistake šŸ˜…
roelof
roelofā€¢3mo ago
can happen im already happy that you try to help me still any ideas ?
shonen295
shonen295ā€¢3mo ago
i think you are using await in useffect callback function you cannot use await keyword like this is useffect
roelof
roelofā€¢3mo ago
oke maybe a stupid question but what is here exaclty the call back function I would think this one :
async function fetchPosts() {
try {
const queryParams = { category: chosenCategory, per_page: 1, _fields: ['date', 'title', 'author', 'content'] };
const response = await apiFetch({
path: addQueryArgs("/wp/v2/posts", queryParams),
});
setPosts(response);
} catch (err) {
console.log(err);
}
}
async function fetchPosts() {
try {
const queryParams = { category: chosenCategory, per_page: 1, _fields: ['date', 'title', 'author', 'content'] };
const response = await apiFetch({
path: addQueryArgs("/wp/v2/posts", queryParams),
});
setPosts(response);
} catch (err) {
console.log(err);
}
}
but that is already async
shonen295
shonen295ā€¢3mo ago
the arrow function that is written at the starting of the useEffect fetchPost function is async that means you can use await keyword inside fetchPosts function only since the callback function in useeffect (the arrow function ) is not async and cannot be you cannot use await keyword directly in useefect
roelof
roelofā€¢3mo ago
sorry but I think it is async
shonen295
shonen295ā€¢3mo ago
the arrow function in useeffect at the starting , see that function is not async
shonen295
shonen295ā€¢3mo ago
DEV Community
Why async callback cannot happen in React useEffect hook?
One common issue that developers experience when utilising the ReactJs useEffect hook is...
shonen295
shonen295ā€¢3mo ago
is this what you are getting as a response from you api ?
roelof
roelofā€¢3mo ago
yep and if I read that article I do exactly what is asked as far as I can see
shonen295
shonen295ā€¢3mo ago
and you want to show the name in the drop down right ?
roelof
roelofā€¢3mo ago
right
shonen295
shonen295ā€¢3mo ago
instead of setCategories(response) trysetCategories(response[0].name)
roelof
roelofā€¢3mo ago
he, I get a very wierd error message :
TypeError: h.map is not a function
TypeError: h.map is not a function
shonen295
shonen295ā€¢3mo ago
have you use h.map anywhere ?
roelof
roelofā€¢3mo ago
No description
roelof
roelofā€¢3mo ago
nope, I never use map anywhere
shonen295
shonen295ā€¢3mo ago
weird
roelof
roelofā€¢3mo ago
yep
shonen295
shonen295ā€¢3mo ago
can you show some more code
roelof
roelofā€¢3mo ago
shonen295
shonen295ā€¢3mo ago
setCategories([response[0].name]) try this
roelof
roelofā€¢3mo ago
no error message but the drop dowm is still empty šŸ˜¦
shonen295
shonen295ā€¢3mo ago
this should have worked
roelof
roelofā€¢3mo ago
sorry
shonen295
shonen295ā€¢3mo ago
you don't have to be its not you fault šŸ˜† const formattedCategories = response.map(category => ({ value: category.id, label: category.name })); setCategories(formattedCategories); this was given by chatgpt have you tried this ? i think this will work we were sending option in wrong format
roelof
roelofā€¢3mo ago
yep. I tried somethig simular but I found it wierd that response have the right format And then I use map to put it also on that format sounds double work to me but it worked well
shonen295
shonen295ā€¢3mo ago
"as long as it works it is fine" XD
roelof
roelofā€¢3mo ago
thanks
missymae#2783
missymae#2783ā€¢3mo ago
maybe the problem can be fixed with response.json() . I made this example
const [example, setExample] = useState("dog fact");

async function catConsole() {
await fetch("https://catfact.ninja/fact").then((res) =>
res.json().then((res) => setExample(res.fact))
);
}

useEffect(() => {
console.log(example); // dog fact
catConsole();
}, []);
console.log(example); // cat fact
const [example, setExample] = useState("dog fact");

async function catConsole() {
await fetch("https://catfact.ninja/fact").then((res) =>
res.json().then((res) => setExample(res.fact))
);
}

useEffect(() => {
console.log(example); // dog fact
catConsole();
}, []);
console.log(example); // cat fact
roelof
roelofā€¢3mo ago
I can try but as far as I know the json part is already done by api-fetch