[英]Re-render a sibling component using hooks
我是新來的反應,我試圖讓一個組件從另一個組件重新渲染。
這是我的代碼:
const Parent = () => {
return (
<div>
<Child1 />
<Child2 />
</div>
)
}
我打算做的是在 Child2 有一些觸發器時更新 Child1。
我能想到的一種方法是讓父組件重新渲染,這樣 Child1 和 Child2 都會被更新。 我試圖通過提升 state 來做到這一點,但它似乎並沒有重新渲染每個子組件。 這是代碼
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 進行更改,並且這些更改需要反映在屏幕上。 它與任何 state 變量無關。
你的問題是一個XY問題。 在給出的示例中, Child1 重新渲染是沒有意義的,因為不需要它。 從評論中,您真正的問題是您更新了一個 API,這應該會改變另一個 API 的響應。 但是,如果您已經知道響應將如何變化,並且它會發生變化,這可以反映在一個 state中,該 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
可以通過某種請求在服務器上添加或修改 state,並且您希望觸發重新渲染以使Child1
刷新 state。
普遍的問題是,只有當道具或其使用的上下文發生變化時,孩子才應該重新渲染。 我看到兩個選項如何解決這個問題:
將請求的處理提升到父級。 將請求的結果作為 props 放入要刷新的子組件中。
通過以某種方式將其設置為“臟”,使兄弟姐妹知道必須重新加載請求。 通過上下文或通過父級路由 state。
如果組件嵌套不太深,通常最好使用選項 1 go。 它可能看起來像這樣:
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>
);
);
作為一個很好的副作用, Child1
和Child2
現在需要更少的邏輯,並且可以獨立於fetchPosts
和sendNewPost
函數進行樣式設置。
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]);
...
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.