Search code examples
javascriptreactjsreact-hooksuse-effectreact-context

React - Access to an object property which is settled in useEffect hook


I'm trying to access a property of an object like this one:

export const ListingDef = {
  assistant: {
      title: 'a'
  },
  contract: {
      title: 'b'
  },
  child: {
      title: 'c'
  }}

I'm using Context and I have a 'listingType' property (empty string) in my state and I define its value in a useEffect hook:

const Listing = ({type}) => {

  const {listingType, setListingType} = useContext(ListingContext);
  useEffect(() => {
      setListingType(type);
  }, [])

  return (
    <>
        <h1 className="listing-title">{ListingDef[listingType].title}</h1>
        <ListingTable/>
    </>
)}

That way, I can access to ListingDef[listingType].title. But I'm facing this issue:

Cannot read property 'title' of undefined

At first render, listingType is equal to empty string so I think I understand why I get this error back.

In other components, I would access to other properties of my object also based on listingType value.

It works if I deal with boolean condition, but is there anyway to avoid if(listingType)... each time I want to access to my object.

(It works fine if I use type directly from the props but I need this value in other components)

Thank you :)

My Context file:

const initialState = {
listingType: '',
listingData: [],
loading: true
}

export const ListingContext = createContext(initialState);

export const ListingProvider = ({children}) => {
const [state, dispatch] = useReducer(ListingReducer, initialState);

const setListingType = (type) => {
     dispatch({
        type: SET_LISTING_TYPE,
        payload: type
    })
}

const getListingData = async (listingType) => {
    try {
        const data = await listObjects(listingType);
        dispatch({
            type: GET_LISTING_DATA,
            payload: data
        })
    } catch (err) {

    }
}

const contextValue = {
    setListingType,
    getListingData,
    listingType: state.listingType,
    listingData: state.listingData,
    loading: state.loading
}

return (
    <ListingContext.Provider value={contextValue}>
        {children}
    </ListingContext.Provider>
)
}

Solution

  • I am relatively new to redux but i don't see the point of using useEffect when the prop type is already working. Either use a default value or add the 'type' prop to the useEffect second param.