在父组件中处理React事件并从子组件中运行一个函数。

huangapple go评论58阅读模式
英文:

React event in parent component and run a function from child component

问题

我在Main组件中有一个项目列表。它包含一个名为Posts的子组件。Posts组件包含一个获取新数据的fetch函数,当用户通过项目滚动时,会触发这个函数。Main组件还包括一个带有筛选和搜索按钮的搜索栏。我在Main组件中点击这个按钮,但我希望的是这个按钮能运行Posts组件内的fetch函数。

我唯一找到的方法是将fetch函数放在父组件Main中,然后将它传递给Posts组件。然而,这样一来,我的Main组件很快就会充满难以管理的代码。在这种情况下,有哪些常见的做法,以及如何升级我的代码呢?

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>
英文:

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>

答案1

得分: 1

在你的Post组件中,你可以添加:

useEffect(() => {
  doFetch(); // 运行fetch函数
}, [props.triggerFetch]);

在你的Main组件中,添加这个属性:

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

当你在Main组件中更新doTriggerFetch时,它会执行Post组件中的doFetch函数。

英文:

In your Post component, you can add:

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

And i your Main, add this attribute:

&lt;Post
   triggerFetch={doTriggerFetch}
   post = {post}
   authToken={authToken}
   authTokenType={authTokenType}
   username={username}
/&gt; 

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

答案2

得分: 0

以下是翻译好的代码部分:

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>
  );
};
英文:

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

const Child = forwardRef((props, ref) =&gt; {
  useImperativeHandle(ref, () =&gt; ({
    log() {
      console.log(&quot;child function&quot;);
    }
  }));

  return &lt;h1&gt;Child&lt;/h1&gt;;
});

const Parent = () =&gt; {
  const ref = useRef();

  return (
    &lt;div&gt;
      &lt;Child ref={ref} /&gt;
      &lt;button onClick={() =&gt; ref.current.log()}&gt;Click&lt;/button&gt;
    &lt;/div&gt;
  );
};

huangapple
  • 本文由 发表于 2023年2月16日 16:30:36
  • 转载请务必保留本文链接:https://go.coder-hub.com/75469580.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定