7

I'm trying to extract data from state. I'm using redux.

const {currentPost } = useSelector(state => state.posts)

I expected to get an object with properties. Instead I get couple of undefined and then I get an object. These undefined on the start causes that I can't destructure further like const {currentPost: {id} } = useSelector(state => state.posts)and returns error that it can't read property of undefined. These posts are obtained by API.

I've tried to workaround it by use a function which checks if this currentPost is undefined and then pass null into these properties. However it's not suitable for project and this solution is error prone.

ArcMech
  • 475
  • 1
  • 5
  • 16
  • 3
    `useSelector(state => state ? state.posts : {})`? – kind user Nov 25 '19 at 19:57
  • The thing is I have to get some properties from it to make some logic in component – ArcMech Nov 25 '19 at 20:00
  • Is `state.posts` being filled in after the application has started? If it exists on startup, then the `useSelector` should return whatever's there immediately. – markerikson Nov 25 '19 at 20:01
  • But what's wrong with creating a separate selector function and check if state.posts exists? Does it have to be a one liner? – kind user Nov 25 '19 at 20:02
  • @markerikson Yeah, this state is filled. The problem is these undefined object that appears first, and then object is loaded. If I console.log it it shows 2/3 times undefined and then object. However it's pecular that if I do ```const {currentPost } = useSelector(state => state.posts)``` then it's ok, if I do ```const {currentPost: {id} } = useSelector(state => state.posts)``` it returns error immediately. – ArcMech Nov 25 '19 at 20:09
  • @kinduser I've done something like this: ```const getId = (currentPost) => { if (currentPost === undefined){ const id = null return id } else { const {id} = currentPost return id } } const postId = getId(currentPost)``` it works, but this solution causes some errors – ArcMech Nov 25 '19 at 20:10
  • What errors does it cause? – kind user Nov 25 '19 at 21:25
  • @kinduser after canceling post it says it cannot read property of null – ArcMech Nov 26 '19 at 07:13
  • 2
    @ArcMech If `state.posts.currentPost` is only available after some api call is made, you need to initialize it with `null` (not `undefined`) or `{}` in the reducer. In the react component, you need to write conditionals to check when `currentPost` is available, and only then destructure further and render stuff. This is a very common thing in react/redux apps. – timotgl Nov 26 '19 at 07:58
  • what is "postsReducer" initial state? – Hagai Harari Nov 26 '19 at 13:34

1 Answers1

10

As I get more experience I want to share my knowledge for future young frontend developers

I'm using redux-toolkit https://redux-toolkit.js.org/ These undefined values are from async operations, so its their behaviour that sometimes before promise is completed return undefined value.

To overcome it and write stable code there is a need to add default values. In redux-toolkit you can use

const slice = createSlice({
  name: 'posts',
  initialState: {
    currentPosts: {
      value: {
        name: ''
      }
    },
    posts: []
  },
  reducers: {
    ...reducers
    },
})

In that case you'll get Object currentPosts, which is not undefined.

ArcMech
  • 475
  • 1
  • 5
  • 16
  • Hello @ArcMech, more than a year late but i can't seem to find a fix to my scenario. Would you mind taking a look at it please? I am using the traditional Redux. https://stackoverflow.com/questions/68018044/using-data-retrieved-from-reduxs-useselector-throws-as-undefined – domster Jun 17 '21 at 12:22
  • 1
    Sure @domster but link is expired/deleted. Does your question is still valid? – ArcMech Jun 19 '21 at 14:03
  • thanks i appreciate it! i found a workaround for it! thank you so much! :) – domster Jun 19 '21 at 17:54