Phát Nguyễn
Phát Nguyễn

Reputation: 185

Use Reselect with ownProps for best practice?

I want select stream info from my redux state. It's work but I very confuse when I try select deep state from my redux state. I want select (state.livestream.subscribeLiveStream[postID].des, state.livestream.subscribeLiveStream[postID].views, ...) with postID from ownProps. Here is my code. My question

  1. Is the code in selector and component good ?
  2. If it's not, please explain for me why.

Thank you for your help. Here is what I have

reducer

state = {
  livestream: {
    subscribeLiveStream: {
      'a': {
        des: 'My stream a',
        views: 0,
        status: 0,
      },
      'b': {
        des: 'My stream b',
        views: 0,
        status: 0,
      }
      // 'a', 'b' is ID
    }
  },
  // other
}

Selector

const livestreamSelector = state => state.livestream;

/* select subscribeLiveStream */
export const selectSubLiveStream = createSelector(
  livestreamSelector,
  livestream => livestream.subscribeLiveStream
);

/* select subscribeLiveStream info */
const getPostID = (_, postID) => postID;
export const makeSelectSubLiveStreamViews = () => createSelector(
  [selectSubLiveStream, getPostID],
  (subLiveStream, postID) => subLiveStream[postID]?.views || 0
);

Using in component:

const LiveStream = ({ postID }) => {
  const selectSubLiveStreamViews = useMemo(makeSelectSubLiveStreamViews, []);
  const views = useSelector(state =>
    selectSubLiveStreamViews(state, postID)
  );
  return (
    <div>
      <p>My stream views: {views}</p>
    </div>
  );
};

Upvotes: 0

Views: 271

Answers (1)

HMR
HMR

Reputation: 39250

You can pass the argument postID as the first argument:

//pass in postId and return a selector function
export const makeSelectSubLiveStreamViews = (postId) => createSelector(
  [selectSubLiveStream],
  (subLiveStream) => subLiveStream[postID]?.views || 0
);

In your component:

//you need to recreate the selector function when postId chages
//  or you'll get the wrong data
const selectSubLiveStreamViews = useMemo(
  ()=>makeSelectSubLiveStreamViews(postId), [postId]
);
//no need to pass postId again, code looks a little cleaner
const views = useSelector(selectSubLiveStreamViews);

Here are some examples how I use reselect with React-redux.

Upvotes: 2

Related Questions