我如何重新渲染另一个主管的组件
How do I rerender a component from another competent
我有 ActivityFeed
个 post。当我单击 ActivityPost
组件中的图标时,它会将 postId 保存在全局状态 (EditPostIndex
) 中,这意味着 CreatePost
和 EditPost
Activity 提要中的组件。当我单击 editpost
图标时,它会弹出我想编辑的 post 的正文
Activity供稿
const ActivityFeed = () => {
const {posts} = useContext(GlobalContext);
const {editPostIndex} = useContext(GlobalContext);
return (
<div id="mobile-activity">
<DeviceNav />
{ editPostIndex === null ?
<CreatePost />
:
<EditPost />
}
{posts.slice(0).reverse().map(post => (
<ActivityPost key={post.id} post={post} />
))}
</div>
)
}
ActivityPost
function ActivityPost({post, index}) => {
const {toggleEditPost} = useContext(GlobalContext);
function updatePost(index){
toggleEditPost(index)
}
}
EditPost.js
const EditPost = () => {
const {posts} = useContext(GlobalContext);
const {updatePost} = useContext(GlobalContext);
const {editPostIndex} = useContext(GlobalContext);
let val = posts[editPostIndex].body;
let [body, setBody] = useState(val);
function editPost() {
//update
}
return (
<div id="make-post">
<div id="create-post">
<textarea value={body} onChange={(e) => setBody(e.target.value)} id="post-activity" placeholder="Tell them what you think."></textarea>
</div>
<div id="create-post-actions">
<button onClick={editPost} id="post">Edit</button>
</div>
</div>
)
}
GlobalState/GlobalContext
const initialState = {
posts: posts,
editPostIndex: null
}
export const GlobalProvider = ({children}) => {
const [state, dispatch] = useReducer(AppReducer, initialState)
function toggleEditPost(index = null){
dispatch({
type: 'TOGGLE_EDIT_POST',
payload: index
})
//alert(index);
}
function updatePost(post){
dispatch({
type: 'UPDATE_POST',
payload: post
})
toggleEditPost(null);
}
}
问题在于,在 EditPost
组件 let val = posts[editPostIndex].body; let [body, setBody] = useState(val);
中,useState 仅呈现一次,因为 EditPostIndex
已经更改。当我单击编辑 post 图标时,如何将 let [body, setBody] = useState(val);
更改为我要编辑的 post 正文?或者重新渲染 EditPost
组件以便重新设置 setBody?
您可以使用redux,它实际上是为此目的而构建的。使用 redux,您可以将组件订阅到 redux 存储,然后推送更新,这将自动更新订阅的组件。
在这种情况下,我会说您需要更多钩子,例如 useState
和 useEffect
来检测上下文中的变化 EditPost.js。
const [postIndex, setPostIndex] = useState(editPostIndex);
useEffect(() => {
if(editPostIndex !== postIndex){
setPostIndex(editPostIndex);
setBody(posts[editPostIndex].body)
}
}, [setPostIndex, postIndex])
我有 ActivityFeed
个 post。当我单击 ActivityPost
组件中的图标时,它会将 postId 保存在全局状态 (EditPostIndex
) 中,这意味着 CreatePost
和 EditPost
Activity 提要中的组件。当我单击 editpost
图标时,它会弹出我想编辑的 post 的正文
Activity供稿
const ActivityFeed = () => {
const {posts} = useContext(GlobalContext);
const {editPostIndex} = useContext(GlobalContext);
return (
<div id="mobile-activity">
<DeviceNav />
{ editPostIndex === null ?
<CreatePost />
:
<EditPost />
}
{posts.slice(0).reverse().map(post => (
<ActivityPost key={post.id} post={post} />
))}
</div>
)
}
ActivityPost
function ActivityPost({post, index}) => {
const {toggleEditPost} = useContext(GlobalContext);
function updatePost(index){
toggleEditPost(index)
}
}
EditPost.js
const EditPost = () => {
const {posts} = useContext(GlobalContext);
const {updatePost} = useContext(GlobalContext);
const {editPostIndex} = useContext(GlobalContext);
let val = posts[editPostIndex].body;
let [body, setBody] = useState(val);
function editPost() {
//update
}
return (
<div id="make-post">
<div id="create-post">
<textarea value={body} onChange={(e) => setBody(e.target.value)} id="post-activity" placeholder="Tell them what you think."></textarea>
</div>
<div id="create-post-actions">
<button onClick={editPost} id="post">Edit</button>
</div>
</div>
)
}
GlobalState/GlobalContext
const initialState = {
posts: posts,
editPostIndex: null
}
export const GlobalProvider = ({children}) => {
const [state, dispatch] = useReducer(AppReducer, initialState)
function toggleEditPost(index = null){
dispatch({
type: 'TOGGLE_EDIT_POST',
payload: index
})
//alert(index);
}
function updatePost(post){
dispatch({
type: 'UPDATE_POST',
payload: post
})
toggleEditPost(null);
}
}
问题在于,在 EditPost
组件 let val = posts[editPostIndex].body; let [body, setBody] = useState(val);
中,useState 仅呈现一次,因为 EditPostIndex
已经更改。当我单击编辑 post 图标时,如何将 let [body, setBody] = useState(val);
更改为我要编辑的 post 正文?或者重新渲染 EditPost
组件以便重新设置 setBody?
您可以使用redux,它实际上是为此目的而构建的。使用 redux,您可以将组件订阅到 redux 存储,然后推送更新,这将自动更新订阅的组件。
在这种情况下,我会说您需要更多钩子,例如 useState
和 useEffect
来检测上下文中的变化 EditPost.js。
const [postIndex, setPostIndex] = useState(editPostIndex);
useEffect(() => {
if(editPostIndex !== postIndex){
setPostIndex(editPostIndex);
setBody(posts[editPostIndex].body)
}
}, [setPostIndex, postIndex])