Reputation: 3589
I'm trying to make this hook resuable through out my application.
This hook retrieves the posts api, i want to be able to call this hook on other pages.
postsHook.tsx
import React, { useEffect, useRef } from "react";
import { connect } from "react-redux";
import { createStructuredSelector } from "reselect";
import {
addContent,
addTitle,
createPostInit,
deleteCommentInit,
initCommentUpdates,
deletePostInit,
dislikePostInit,
getPostsInit,
likePostInit,
notificationInit,
postCommentInit,
} from "../../actions/postActions";
import { getBodyError, getIsNotified, getNotification, getPopPosts, getPosts, getTitleError, getUser, postContent, title } from "./../../selectors/selectors";
const mapDispatchToProps = (dispatch: any) => ({
getPostsInit: () => dispatch(getPostsInit()),
initCommentUpdates: () => dispatch(initCommentUpdates()),
notificationInit: () => dispatch(notificationInit()),
likePost: (id: number) => dispatch(likePostInit(id)),
addTitle: (data: string) => dispatch(addTitle(data)),
addContent: (data: string) => dispatch(addContent(data)),
postCommentInit: (commentData: object) => dispatch(postCommentInit(commentData)),
dislikePost: (id: number) => dispatch(dislikePostInit(id)),
deletePostInit: (id: number, userId: number) => dispatch(deletePostInit(id, userId)),
deleteComment: (id: number, postId: number, userId: number) => dispatch(deleteCommentInit(id, postId, userId)),
createPostInit: (postData: object) => dispatch(createPostInit(postData)),
});
const mapStateToProps = createStructuredSelector({
posts: getPosts(),
popPosts: getPopPosts(),
user: getUser(),
isNotified: getIsNotified(),
titleError: getTitleError(),
bodyError: getBodyError(),
title: title(),
postContent: postContent(),
notification: getNotification(),
});
function PostsHooks(props) {
const didMountRef = useRef<Object>();
React.useEffect(() => {
if (!didMountRef.current) {
props.getPostsInit();
props.initCommentUpdates();
console.log("test");
} else {
console.log("this is component didupdate");
}
}, []); // array prevents an infinite loop
return null;
}
export default connect(mapStateToProps, mapDispatchToProps)(PostsHooks);
I want to call this hook in landing component, however im gettting
NOTE: Exotic components are not callable.
Expected 1 arguments, but got 0.ts(2554) index.d.ts(323, 10): An argument for 'props' was not provided.
What am i doing wrong ?
Landing.tsx
import React, { Fragment, useRef, Component } from "react";
import PostList from "../forms/postList/postList";
import GridHoc from "../hoc/grid";
import Typography from "@material-ui/core/Typography";
import PostsHook from "./../common/postsHook";
function Landing(props) {
const [posts] = PostsHook();
// const didMountRef = useRef<Object>();
// React.useEffect(() => {
// if (!didMountRef.current) {
// props.getPostsInit();
// props.initCommentUpdates();
// console.log("test");
// } else {
// console.log("this is component didupdate");
// }
// }, []); // array prevents an infinite loop
return (
<Fragment>
<Typography variant="h6" align="left">
Post's from our users
</Typography>
{/* <PostList
likePost={props.likePost}
deletePost={props.deletePostInit}
deleteComment={props.deleteComment}
dislikePost={props.dislikePost}
posts={props.posts}
currentUser={props.user}
postComment={props.postCommentInit}
isNotified={props.isNotified}
getNotifications={props.notificationInit}
notification={props.notification}
/> */}
</Fragment>
);
}
export default GridHoc(Landing);
Upvotes: 0
Views: 399
Reputation: 19194
From react docs:
A custom Hook is a JavaScript function whose name starts with ”use” and that may call other Hooks
So the first step would be to change the naming to:
function usePostsHook() {
...
}
const Landing() {
usePostsHook();
...
}
A connect
function from redux is used on components and since a custom hook is not a component, you cannot use it there. Luckily, redux ships with two custom hooks: useSelector
and useDispatch
to provide the same functionality.
function usePostsHook() {
// getPosts would have to be a fn that takes store and returns posts.
const posts = useSelector(getPosts());
const dispatch = useDispatch();
useEffect(() => {
dispatch(getPostsInit());
dispatch(initCommentUpdates());
}, []);
return [posts];
}
const Landing() {
const [posts] = usePostsHook();
...
}
On the API side, note that you are trying to return posts
from the hook
, but the hook is infact returning null
Upvotes: 2