2

I have simple nextjs app where i want to save and print state to fetchData

This is my code

const Room = () => {
  const router = useRouter();
  const [fetchData, setFetchData] = useState("");

  useEffect(() => {
    if (router.asPath !== router.route) {
      getDataNames();
      console.log(fetchData); // Empty
    }
  }, [router]);

  const getDataNames = async () => {
    try {
      await fetch("http://localhost:1337/rooms?_id=" + router.query.id)
        .then((response) => response.json())
        .then((jsonData) => setFetchData(jsonData) & console.log(jsonData)); // Data are logged in console
    } catch (e) {
      console.error(e);
    }
  };

Problem is that fetchData is empty on console log but jsonData gaves me actual data. And i have no idea what can be problem.

Michaelo
  • 579
  • 1
  • 5
  • 13
  • Doing `setFetchData(jsonData) & console.log(jsonData)` you are actually executing the last condition that it's the `console.log`, try removing it so it would be `setFetchData(jsonData)`. – AdriSolid Feb 26 '21 at 07:28
  • @AdriSolid Thanks for idea. Thats what i started with i just added console log to show that there are data in `jsonData` but good to know that `setFetchData` is not executed. But result after removing is still the same. – Michaelo Feb 26 '21 at 07:30

2 Answers2

1

Ok so 3 things here. Firstly, your useEffect doesn't re-run when your fetchData value changes. You need to add it to the dependency list:

  useEffect(() => {
    if (router.asPath !== router.route) {
      getDataNames();
      console.log(fetchData); // Empty
    }
  }, [router, fetchData]);

this way the effect will run when fetchData changes. And of course it will only console.log it if that condition inside the effect's if condition is satisfied.

Secondly, you're mixing async/await and .then/.catch syntax, don't do that. Use one or the other. In this case you can just remove the await keyword and try/catch block, and use your existing .then code, and add a .catch to it to catch any errors.

Finally, & in Javascript is the bitwise AND operator, so not sure why you were using it there. If you think it means "and also do this", then that's incorrect. Just put the .then function inside curly braces and call the setFetchData and console.log statements one after the other:

.then((jsonData) => {
    setFetchData(jsonData);
    console.log(jsonData)
});
codemonkey
  • 7,325
  • 5
  • 22
  • 36
Jayce444
  • 8,725
  • 3
  • 27
  • 43
  • 1
    Thank you when i added `fetchData` to useEffect() dependency list it prints console log. Only problem is that it created infinity cycle because getDataNames() change fetchData so its called again and again and again. And thanks for other two thing it helped me a lot :) – Michaelo Feb 26 '21 at 07:54
  • @Michaelo haha yes true that will happen, but that's just because of how you set up your code. The effect calls that API and sets the state, but the router stuff doesn't change so it will just keep happening. You might need to rearrange your logic so that the cause-and-effect chain of your code is correct and free of loops. Or maybe the fetched data shouldn't need to be in the effect's dependency list in the first place - but without more code/context and desired use case explained, I can't say. – Jayce444 Feb 26 '21 at 08:02
1
 useEffect(() => {

      console.log(fetchData);
    
  }, [fetchData]);

use this hook to log your data

Anh Tuan
  • 1,113
  • 5
  • 12