1

I am trying to fetch data during ComponentWillMount lifecycle in server side using useMemo()

  const [text, setText] = useState('hello')
  
  const fakeApiCall = new Promise(resolve => 'world')
  
  useMemo(async () => {
    const value = await fakeApiCall
    setText(value)
  }, [])

Doing this the value for text will still remain hello instead of world. Is it possible to achieve this? Why is this not working?

John Winston
  • 1,260
  • 15
  • 30
  • If I remember correct, for a given pair of dependencies, `useMemo` returns a value. So ideally, you should pass dependencies. Also, `useMemo(() => {}, [])` is not `componentWillMount`. Try `useEffect(() => {}, [])` instead as API data should be fetched after component is mounted. Else, you can have lag in your component – Rajesh Dec 15 '20 at 07:39
  • 2
    `useMemo` is for memoizing a value, there should be ***zero*** side-effects. I think you are wanting to use the `useEffect` hook to initialize state. Also, for all practical purposes, `componentWillMount` is deprecated, use the equivalent of `componentDidMount`, which is `useEffect` with an empty dependency array. – Drew Reese Dec 15 '20 at 07:40
  • @DrewReese But if I use `useEffect`, it would not be triggered in server side, and I cannot only fetch data in client side. – John Winston Dec 15 '20 at 07:52
  • Right, it gets a little funky with react hooks, mounting, and SSR. A google search finds a bunch of work arounds. – Drew Reese Dec 15 '20 at 07:53
  • In any case, you will need to put the `fakeApiCall` creation *inside* that hook, where you `await` the promise. – Bergi Dec 15 '20 at 07:59

2 Answers2

1

as you know, the await will be return a 'promise object', and after the response came out it will be replaced with 'promise value', all you need is a falge to detect whenever you got a success response .

your code will seems like

  const [text, setText] = useState('hello')
  
  const fakeApiCall = new Promise(resolve => 'world')
  
  const [flage,setFlag] = useState(false) //adding whatever your flag name

  useMemo(async () => {
    const response = await fakeApiCall

    if(response.Success) // you will check on response result
    {
     setText(value)
    }
  }, [])

or you can check on this Promise.resolve(valueOrPromiseItDoesntMatter).then

0

Practically, you can achieve all you need here with useState and useEffect:

  const [text, setText] = useState('hello')
  
  const fakeApiCall = new Promise(resolve => 'world')

  useEffect(() => {
    fakeApiCall()
      .then(response => { setText(response) })
  },[])

Note that you do not need to make the function within the useEffect hook async as it will resolve normally through typical promise flow.

As we have passed nothing into the dependency array, this hook will execute once on component mount and effectively memoise the response in the text variable.

timbhison
  • 101
  • 7