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