devYuraKim / react

udemy - jonas schmedtmann
0 stars 0 forks source link

Re12-atomic-blog > src > context | lost in context custom hook #19

Closed devYuraKim closed 1 week ago

devYuraKim commented 1 week ago

Completely lost. I know that I need to return functions somewhere that have access to the value, but that's it.

import { createContext } from "react";

function PostContext() {
  const PostContext = createContext();

  <PostContext.Provider
    value={{
      posts: searchedPosts,
      onAddPost: handleAddPost,
      onClearPosts: handleClearPosts,
    }}
  ></PostContext.Provider>;
}

export default PostContext;
devYuraKim commented 1 week ago
  1. Create the context outside all functions using createContext.
  2. Define the ContextProvider function, including all the related states and returning <Context.Provider value={...}>{children}</Context.Provider>
  3. Define the custom hook using useContext to access and return the context.
  4. export { ContextProvider, useContext }
  5. if necessary, retrieve state from other contexts like const { searchQuery } = useSearchContext().
function createRandomPost() {
  return {
    title: `${faker.hacker.adjective()} ${faker.hacker.noun()}`,
    body: faker.hacker.phrase(),
  };
}

const PostContext = createContext();

function PostProvider({ children }) {
  const [posts, setPosts] = useState(() =>
    Array.from({ length: 30 }, () => createRandomPost())
  );

  const { searchQuery } = useSearchContext();

  // Derived state. These are the posts that will actually be displayed
  const searchedPosts =
    searchQuery.length > 0
      ? posts.filter((post) =>
          `${post.title} ${post.body}`
            .toLowerCase()
            .includes(searchQuery.toLowerCase())
        )
      : posts;

  function handleAddPost(post) {
    setPosts((posts) => [post, ...posts]);
  }

  function handleClearPosts() {
    setPosts([]);
  }

  return (
    <PostContext.Provider
      value={{
        posts: searchedPosts,
        onAddPost: handleAddPost,
        onClearPosts: handleClearPosts,
      }}
    >
      {children}
    </PostContext.Provider>
  );
}

function usePostContext() {
  const context = useContext(PostContext);
  return context;
}

export { PostProvider, usePostContext };