使用钩子重新渲染同级组件



我是新手,我正在尝试从另一个组件重新渲染一个组件。

这是我的代码:

const Parent = () => {
return (
<div>
<Child1 />
<Child2 />
</div>
)
}

我打算做的是在Child2触发时更新Child1。

我可以想到的一种方法是让父组件重新渲染,这样Child1和Child2都会更新。我试图通过提升状态来实现这一点,但它似乎没有重新渲染每个子组件。这是代码

const Parent = () => {
const [value, setValue] = useState('')
const handlePost = (newValue) => {
setValue(newValue)
}
return (
<div>
<Child1 />
<Child2 onPost={handlePost} />
</div>
)
}
const Child2 = (props) => {
// This function is executed when there is a trigger. 
// In this case, when a post request is made to the server
const onPost() => {
props.handlePost('new value')
}
}

编辑:组件需要重新渲染的原因是,它们正在对API进行更改,这些更改需要反映在屏幕上。它与任何状态变量无关。

您的问题是XY问题。在给出的例子中,Child1重新发送程序没有意义,因为没有必要这样做。从评论中,您的真正问题是您更新了一个API,这应该会改变另一个API的响应。然而,如果您已经知道响应将如何改变,并且它将改变,这可以反映在两个API调用的一个状态中:

function useEntries() {
const [entries, setEntries] = useState([]);
useEffect(() => {
setEntries(getEntries());
}, []);
function addEntry(entry) {
postEntry(entry);
setEntries(prev => [...prev, entry]);
}
return { entries, addEntry };
}
function Parent() {
const { entries, addEntry } = useEntries();
return <>
<Entries entries={entries} />
<AddEntry addEntry={addEntry} />
</>;
}


从帖子中的评论来看,似乎Child1显示了GET请求的结果(在Child1中完成(。Child2可以通过某种请求在服务器上添加或修改该状态,并且您希望触发重新渲染以使Child1刷新状态。

一般的问题是,只有当道具或他们使用的上下文发生变化时,孩子们才应该重新渲染。我看到了两种方法:

  1. 将请求的处理提升到父级。将请求的结果作为道具放入要刷新的子组件中。

  2. 通过将请求设置为"0",使兄弟姐妹知道必须重新加载请求;脏的";在某种程度上。通过上下文或通过父级路由状态。

如果组件嵌套不太深,通常最好使用选项1。它可能看起来像这样:

const Parent = () => {
const [posts, setPosts] = useState([]);
const fetchNewestPosts = useCallback(async () => {
const fetched = await fetchPosts();
setPosts(fetched);
}, [fetchPosts, setPosts]);
const handleSubmit = useCallback(async (event) => {
const newPost = getValuesFromSubmitEvent(event);
await sendNewPost(newPost);
// you could even set the posts here to what you think the 
// send request will result in (see Jonas Wilms answer), like
// setPosts(posts => [newPost, ...posts]);
await fetchNewestPosts();
}, [fetchNewestPosts, getValuesFromSubmitEvent, sendNewPost]);
useEffect(() => {
fetchNewestPosts();
}, [fetchNewestPosts]);
return (
<div>
<Child1 posts={posts} />
<Child2 submitNewPost={submitNewPost} />
</div>
);
);
const Child1 = ({posts}) => {
return (
<ul>{posts.map(post => <li key={post.id}>post.title</li>)}</ul>
);
);
const Child2 = ({submitNewPost}) => {
return (
<form onSubmit={submitNewPost}>...</form>
);
);

作为一个很好的副作用,Child1Child2现在需要更少的逻辑,并且可以独立于fetchPostssendNewPost函数进行样式设置。

Ciao,假设Child1必须在handlePost上重新渲染。您的父组件将是:

const Parent= () => {
const [value, setValue] = useState('')
const [rerender, setrerender] = useState(false)
const handlePost = (newValue) => {
setValue(newValue);
let setrerender_temp = rerender;
setrerender(!setrerender_temp);
}
return (
<div>
<Child1 rerender={rerender} />
<Child2 onPost={handlePost} />
</div>
)
}

然后,在您的Child1组件中:

import React, { useReducer, useEffect } from 'react';
...
export default function Child1(props) {
const [,forceRender] = useReducer((s) => s+1, 0);
useEffect(() => forceRender(), [props.rerender]);
...
}

相关内容

  • 没有找到相关文章

最新更新