-1

Why "Cards" still doesn't receive the passed value from selectedCountryInfo

I just tried passing await to the variable, still doesn't work. "Cards" still don't receive value. <----solution: when there are have 2 setStates, should use 2 variables, not use 1 variable.(I guess if there are 3 setStates use 3 variables and so on)

I've been thinking about it for over 12 hours and can't think of a solution. Because the default value of useState cannot put async/await.

(fetchedCountries is array,selectedCountryInfo is object)

const App = () => {
  const [fetchedCountries, setFetchedCountries] = useState([]);
  const [selectedCountryInfo, SetSelectedCountryInfo] = useState();

  useEffect(() => {
    const myCountries = async () => {
      const countries = await worldWideCountries();
      setFetchedCountries(countries);
      SetSelectedCountryInfo(fetchedCountries[0]);
    };
    myCountries();
  }, []);

  return (
    <div>
      <Cards selectedCountryInfo={selectedCountryInfo} />
    </div>
  );

Solution:(from the 3 lines)

const countries = await worldWideCountries();
setFetchedCountries(countries);
const ww = countries[0];
SetSelectedCountryInfo(ww);
Junior
  • 27
  • 7
  • 1
    Does this answer your question? [The useState set method is not reflecting a change immediately](https://stackoverflow.com/questions/54069253/the-usestate-set-method-is-not-reflecting-a-change-immediately) – David Jul 20 '22 at 18:00
  • 3
    In short: State updates are asynchronous. Assign the result of `await worldWideCountries()` to a variable and use it in both of your state update operations. (This has nothing to do with `useEffect`.) – David Jul 20 '22 at 18:01
  • Why would `useEffect` update the first state? When the component runs for the first time `useEffect` is loaded, so the state it updates can only be used in the next render cycle. – Konrad Jul 20 '22 at 18:01
  • @David Sorry, `await worldWideCountries()` to a variable still not work – Junior Jul 20 '22 at 18:49
  • @Junior: What "doesn't work" about it? Did you read and understand the proposed duplicate question and answer(s)? What changes did you make to your code? In what specific way does that new code not work as expected? – David Jul 20 '22 at 18:56
  • @David Because your code is the same as mine, the problem is not whether to put variables – Junior Jul 20 '22 at 18:58
  • @Junior: No, putting the value in a variable is not the same as your code, which doesn't put the value in a variable. `var temp = await worldWideCountries(); setFetchedCountries(temp); SetSelectedCountryInfo(temp[0]);` Read and understand the linked proposed duplicate. State updates are *asynchronous*. So your code is calling `SetSelectedCountryInfo` with the *current value* of `fetchedCountries`, which is an empty array. – David Jul 20 '22 at 19:01
  • @David ..........I said I put the variable and it still doesn't receive the value – Junior Jul 20 '22 at 19:04
  • 1
    @Junior: According to the code shown that isn't what you're doing. Please update the question to correct the problem of the asynchronous state updates and indicate specifically what problem you are observing. If there is more than one problem in the code, any other problem is currently being obscured by the problem of not properly handling state updates. – David Jul 20 '22 at 19:04
  • 1
    @Junior have you tried checking what `await worldWideCountries()` returns? – Konrad Jul 20 '22 at 19:09
  • 1
    @Junior: Your updated version still has the same problem here: `SetSelectedCountryInfo(fetchedCountries[0]);` The problem is not *a lack of a variable*. The problem is that *you are not using state correctly*. You can correct this by *using the value in the variable that you set* instead of using the state value. Now would be a good time to stop assuming we're wrong and to read and understand the linked proposed duplicate and to try the exact solution which was [recommended above](https://stackoverflow.com/questions/73056203/how-to-get-cards-to-receive-value-smoothly#comment129031153_73056203) – David Jul 20 '22 at 19:12
  • @KonradLinkowski it has value. – Junior Jul 20 '22 at 19:16

1 Answers1

0

You probably want to use conditional rendering

const App = () => {
  const [fetchedCountries, setFetchedCountries] = useState([]);
  const [selectedCountryInfo, SetSelectedCountryInfo] = useState();

  useEffect(() => {
    const myCountries = async () => {
      setFetchedCountries(await worldWideCountries());
      SetSelectedCountryInfo(fetchedCountries[0]);
    };
    myCountries();
  }, []);

  return (
    <div>
      { selectedCountryInfo && <Cards selectedCountryInfo={selectedCountryInfo} /> }
    </div>
  );
}
Konrad
  • 21,590
  • 4
  • 28
  • 64
  • The existence of "Cards" is not the point, the point is to receive the value – Junior Jul 20 '22 at 18:44
  • The problem isn't in the rendering, the problem is in the asynchronous nature of state updates. `fetchedCountries` is an empty array when `SetSelectedCountryInfo` is being called. – David Jul 20 '22 at 19:03