0
   const [dataDB, setDataDB] = useState(null);
   const [dataContent, setDataContent] = useState(null);
...
   useEffect(() => {
      fetch('some-url.com')
         .then((res) => res.json())
         .then((dataDB) => {
            setDataDB(dataDB)
            console.log("dataDB: " + dataDB); // this works fine
         })
         .then((dataContent) => {
            const role = tabs.find(x => x.id == dataDB[0][0]+1)
            setDataContent(role);
            console.log("dataContent: " + dataContent); // getting null here
         })
   }, [])

I can't get the second setState (setDataContent) to work. I tried putting the setDataDB and setDataContent together but still having the same issue. It has to be I'm not understanding promises.

Edit: Was reading https://nextjs.org/docs/basic-features/data-fetching/client-side I'm trying to update dataContent based on value of dataDB.

Lewis
  • 135
  • 1
  • 10
  • Don't rely on dataDB being updated in the second then. – evolutionxbox Mar 06 '23 at 12:20
  • IMO this was wrongfully closed. The issue isn't a misunderstanding of `useState`; it's a misunderstanding of `.then`. `dataContent` is going to be the value you return from your `.then(dataDB=>` call, which is currently `undefined`. – Dylan Mar 06 '23 at 12:24
  • @Dylan: It looks like it's potentially a combination of both. The use of local variables shadowing component-level variables is likely confusing the OP here. (Edit: Though, if the OP is expecting the `dataContent` argument in the last `.then()` callback to have a value, why isn't that value *used* for anything? It's only being logged, which could have been done in the previous `.then()` callback.) – David Mar 06 '23 at 12:28
  • 1
    That said, the shadowing of `dataDB` and `dataContent` the _state_ values, with `dataDB` and `dataContent` the anonymous function _arguments_ is making OP's intentions a bit unclear. (edit: oh I wrote this before I refreshed and saw your comment @David) – Dylan Mar 06 '23 at 12:28
  • I'm trying to update dataContent based on value of dataDB. How would I go about doing that? – Lewis Mar 06 '23 at 12:34
  • @Lewis: Regarding the edit... If `dataContent` is derived from `dataDB` then should the former even be its own state value in the first place? Keeping duplicated data synchronized is hard, and generally the solution is to not duplicate it. Values derived from state can be calculated when rendering. But if you *really want* to store it in its own state value, you can wrap that update in a `useEffect` that updates the `dataContent` state value whenever `dataDB` changes. (Or, in this specific case, update it directly from the deserialized JSON, exactly where you update `dataDB`.) – David Mar 06 '23 at 12:35
  • @David better `useMemo` for the derived state, than `useState + useEffect` – Thomas Mar 06 '23 at 12:37
  • @Thomas: That's essentially what I mean by deriving the value on render. In most cases `useMemo` probably isn't even needed as the difference is negligible. (In this case it looks like it's just a simple call to `.find()`.) Overall the point being that `dataContent` doesn't really need to be a state value at all here. – David Mar 06 '23 at 12:39

0 Answers0