I have an ActivityFeed
of posts. When I click on an icon in the ActivityPost
component it saves the postId in a global state (EditPostIndex
) that's meant to act like a toggle for the CreatePost
and EditPost
component in the Activity feed. When I click on the editpost
icon it brings up the body of the post that I'm suppose to edit
ActivityFeed
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);
}
}
The problem is that in EditPost
component let val = posts[editPostIndex].body; let [body, setBody] = useState(val);
the useState only renders once because the EditPostIndex
is already changed. How do I make it so when I click on the edit post icon the let [body, setBody] = useState(val);
changes to the posts body that I want to edit? Or rerender the EditPost
component so setBody is set again?
In this case, I'd say you'd need more hooks like useState
& useEffect
to detect a change in your context EditPost.js.
const [postIndex, setPostIndex] = useState(editPostIndex);
useEffect(() => {
if(editPostIndex !== postIndex){
setPostIndex(editPostIndex);
setBody(posts[editPostIndex].body)
}
}, [setPostIndex, postIndex])