英文:
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(() => {
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.
答案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) => {
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>
);
};
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。


评论