skip to Main Content

I have a list of items in my Main component. It has a child component called Posts. The Posts component contains a fetch function that retrieves new data when the user scrolls down through the items. The Main component also includes a search bar with a filter and search button. I click this button in the Main component, but what I want is that this button runs fetch function inside Posts component.

The only way I find is to put the fetch function inside parent Main and pass it down to Posts. However, this way my Main will soon be full of unmanageable code? What is common practice for such tasks and how could I upgrade my code?

Main:

//...
function Main({posts, authToken, authTokenType, username, userId}) {
//...
     return (
        <div>
        <Posts 
          authToken={authToken}
          authTokenType={authTokenType}
          username={username}
        />

Posts:

//...
function Posts({authToken,authTokenType, username}) {
//...
    const [posts, setPosts] = useState([]);
    const fetchData = () => {
        fetch(BASE_URL + `post/all?page=${page}`)
        //...
        return(
          <div>
              <InfiniteScroll
               dataLength={posts.length}
               next={fetchData}
               hasMore={hasMore}
               loader={<h4>Loading...</h4>}
             >
              <Row>
              {posts.map((post, index) => (
                 <Col lg={3}>
                 <Post
                 post = {post}
                 authToken={authToken}
                 authTokenType={authTokenType}
                 username={username}
                 /> </Col>
          ))}</Row>
        </InfiniteScroll>

2

Answers


  1. I dont know if this is the best solution but you could use the useImperativeHandle hook and forwardRef:

    const Child = forwardRef((props, ref) => {
      useImperativeHandle(ref, () => ({
        log() {
          console.log("child function");
        }
      }));
    
      return <h1>Child</h1>;
    });
    
    
    const Parent = () => {
      const ref = useRef();
    
      return (
        <div>
          <Child ref={ref} />
          <button onClick={() => ref.current.log()}>Click</button>
        </div>
      );
    };
    
    Login or Signup to reply.
  2. In your Post component, you can add:

    useEffect(() => {
      doFetch(); // Run the fetch function
    }, [props.triggerFetch]);
    

    And i your Main, add this attribute:

    <Post
       triggerFetch={doTriggerFetch}
       post = {post}
       authToken={authToken}
       authTokenType={authTokenType}
       username={username}
    /> 
    

    When you update doTriggerFetch in the Main component, it will execute the doFetch function in the Post component.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search