0

We have a really large codebase with 271 class components and the old redux (not redux toolkit).

We are in the process of migrating to redux toolkit - and adoption RTK-Query as our async state manager. We will migrate redux-saga based functionality to rtk-query and trim our reducers.

For functional components it's very easy to do both things

  1. get data, loading state
  2. dispatch the action to ask for this data.
 const {data: posts, isLoading, isError, isSuccess } = usePosts();

But how do I do this in a class based component...

componentDidMount(){
  //what to dispatch here ?
}

render(){
   const {data: posts, isLoading, isError, isSuccess } = fromWhichPlace;
}

1 Answer 1

2

We specifically cover this topic in our docs:

Per those pages, you'd need to do something along the lines of:


const mapState = (
  state: RootState,
  ownProps: RouteComponentProps<{ id: string }>
) => ({
  id: Number(ownProps.match.params.id),
  post: endpoints.getPost.select(Number(ownProps.match.params.id))(state),
  updatePostState: endpoints.updatePost.select(ownProps.match.params.id)(state), // TODO: make selectors work with the requestId of the mutation?
  deletePostState: endpoints.updatePost.select(ownProps.match.params.id)(state)
});

const mapDispatch = {
  getPost: endpoints.getPost.initiate,
  updatePost: endpoints.updatePost.initiate,
  deletePost: endpoints.deletePost.initiate
};

const connector = connect(mapState, mapDispatch);
type PostDetailProps = ConnectedProps<typeof connector> & RouteComponentProps;

export class PostDetailComp extends React.Component<PostDetailProps> {
  state = {
    isEditing: false
  };

  componentDidMount() {
    const { id, getPost } = this.props;
    getPost(id);
  }

  componentDidUpdate(prevProps: PostDetailProps) {
    const { id, getPost } = this.props;
    if (id !== prevProps.id) {
      getPost(id);
    }
  }

  render() {
    const { isEditing } = this.state;
    const {
      // state
      id,
      post: { data: post, isLoading: isPostLoading },
      updatePostState: { isLoading: isUpdateLoading },
      deletePostState: { isLoading: isDeleteLoading },

      // actions
      updatePost,
      deletePost
    } = this.props;

    // snip rendering logic
}

export const PostDetail = connector(PostDetailComp);

However, we would strongly recommend that you convert these components to function components instead, and use the auto-generated query hooks! It will be much simpler and easier to use, and the hooks have a lot of built-in functionality that will be hard to replicate by hand in class components.

Sign up to request clarification or add additional context in comments.

2 Comments

well, we have 271 class components and although I do re-write every class to FC where-ever possible - convincing everyone else is a major problem
You don't have to rewrite every component right away :) But I can seriously tell you that the work of rewriting the components that need this data to be function components using query hooks will be less effort than trying to manage the RTKQ subscriptions yourself in class components.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.