Home > Software engineering >  How to get redux state before render for child component prop?
How to get redux state before render for child component prop?

Time:10-09

I have a component that renders another component, and it depends on the currentUser state in redux. However, upon initial load, the value is undefined. How do I enforce that the value is defined before proceeding?

The component with the state:

import { Grid, Typography } from "@material-ui/core"
import { makeStyles } from "@material-ui/styles"
import { useEffect, useState } from "react"
import DataScroll from "./navigation/DataScroll"
import Post from '../components/partsbin/Post'
import SidePanelCard from '../components/SidePanelCard'
import { getPosts } from "../gql/queries"
import { useSelector } from 'react-redux'
const theme = makeStyles({})

export default function HappeningNow(props: any) {
  const styles = theme()
  const { currentUser } = useSelector(({ uiState }: any) => uiState)

  const handleGetPosts = async (offset: number, limit: number) => {
    try {
      const data = await getPosts(offset, limit, null, currentUser?.uid || null)
      console.log('params being passed: ', offset, limit, null, currentUser?.uid)
      console.log('data returned', data)
      return data
    } catch(e) {
      return e
    }
  }

  return (
    <Grid container flexDirection="column">
      <Grid item>
        <Typography
          variant="h6"
          sx={{ fontWeight: "bold", textAlign: "center" }}
        >
          Happening Now
        </Typography>
      </Grid>
      <Grid item>
        <DataScroll ItemComponent={SidePanelCard} limit={12} getApiItems={(offset: number, limit: number) => handleGetPosts(offset, limit)} />
      </Grid>
    </Grid>
  )
}

As you can see, I'm setting currentUser via useSelector, but the query handleGetPosts is firing before currentUser is being defined. How do we guarantee that the value is set? Is it good practice to wrap a global state with local state? Is there a way to use useSelector in a useEffect? Not sure where to begin. Thanks in advance!

CodePudding user response:

When you get the value currentUser the component will re-render. So you may add a simple condition to check if currentUser is available or not. Like,

{currentUser && <DataScroll ItemComponent={SidePanelCard} limit={12} getApiItems={(offset: number, limit: number) => handleGetPosts(offset, limit)} />} .

Now handleGetPosts should get triggered only if currentUser is set.

  • Related