Why is my local state being overridden? React

I’m using useState hook to manage state. Whenever a user clicks likePost, setData is called with newData. This causes the state to update as seen in the images and the item loses postedBy name item.postedBy.name becomes undefined. This causes the user-title div to empty and collapse.

before likePost

after likePost

The relevant code includes:

const Home = () => {
const [data, setData] = useState([]);
// for access to user who's logged in, use context
const {state, dispatch} = useContext(UserContext);
useEffect(()=>{
    fetch('/allposts', {
        headers:{
            "Authorization":"Bearer " + localStorage.getItem("jwt")
        }
    }).then(res=>res.json())
    .then(result=>{
        console.log(result);
        setData(result.posts);
    });     
}, []);

const likePost = (item, id) => {
    fetch('/like', {
        method: "put", 
        headers: {
            "Content-Type":"application/json",
            "Authorization":"Bearer " + localStorage.getItem("jwt")
        },
        body: JSON.stringify({
            postId:id
        })
    }).then(res=>res.json())
    .then(result=>{
        const newData = data.map(item=>{
            if(item._id == result._id){
                return result;
            }else{
                return item;
            }
        })
        setData(newData);
    }).catch(err=>{
        console.log(err);
    })
};

and

return (
    <div className="home">
        {
            postsReversed.map(item=>{   
                return(
                    <div className="card home-card" key={item._id}>
                        <h5 className="user-title"><Link to={item.postedBy._id !== state._id ? "/profile/"+item.postedBy._id : "/profile/"}>{item.postedBy.name}</Link>{item.postedBy._id == state._id
                            && <i className="material-icons" style={{
                                float: "right"
                        }}
                        onClick={()=>deletePost(item._id)}
                        >delete</i>
                        }</h5>
                        <div className="card-image">
                            <img src={item.photo} />
                        </div>
                        <div className="card-content">
                            <div>
                            {item.likes.includes(state._id)
                                ?
                            <i className="material-icons"
                                onClick={()=>{unlikePost(item._id)}}
                            >thumb_down</i>
                                : 
                            <i className="material-icons"
                                onClick={()=>{likePost(item._id)}}
                            >thumb_up</i>
                            }

Answer

This seems to work as intended, you’re replacing an item from the data array with the one that you get as a response from the /like endpoint. You can either change your server to return the same data structure for an item as /allposts or use something like:

....
if (item._id == result._id) {
    return { ...item, likes: result.likes };
}
....

To only update part of the item.