I have an application where user has lot of profile information e.g LinkedIn profile. I need to update user's profile. I create a context at root level component i.e App and share that context using useContext hook in multiple profile components. The user can change the profile attributes like title, summary of his profile from any sub component and it updates the global context. When the global context refreshes then it causes all the child components that consume the context to re-render. How can I avoid re-render of other components where there was no change.
Here is my code:
profile-context.tsx
import React from 'react';
let ProfileContext = React.createContext({});
export default ProfileContext;
App.tsx
import React, { useEffect, useState } from 'react';
import UserProfile from './user-profile';
import ProfileContext from './context/profile-context';
const App = () => {
const [userProfile, setProfileInfo] = useState({});
const update = (profile: any, section: any, attributes: any) => {
let updatedState = UserService.updateProfile(profile, section, attributes);//This returns the updated state
setProfileInfo((prevState: any) => updatedState);
};
useEffect(() => {
setProfileInfo(() => UserService.fetchProfileInfo());
}, []);
return (
<>
<ProfileContext.Provider value={{ userProfile, update }}>
<UserProfile />
</ProfileContext.Provider>
</>
);
};
export default App;
user-profile.tsx
import React, { FC } from 'react'
import Header from './profile/header';
import About from './profile/about';
import Experience from './profile/experience';
import Education from './profile/education';
const UserProfile: FC = () => {
return (
<>
<Header />
<About />
<Experience />
<Education />
</>
);
};
export default UserProfile;
about.tsx
import React, { FC, useContext } from 'react';
import ProfileContext from '../../../context/profile-context';
const About: FC = () => {
let { userProfile, update } = useContext(ProfileContext);
const changeProfileAttribute = (section: any, attribute: string) => {
update(userProfile, section, { attribute: 'Software Engineer' });
};
return (
<>
<div className="user-profile">
<h1
className="professional-title"
onClick={() => {
changeProfileAttribute('about', 'title');
}}
>
{userProfile.about.title}
</h1>
</div>
</div>
</>
);
};
export default About;
As I make a change About component by clicking on professional title (dummy function to update the state attribute) the whole application re-renders. I want that only about section of the profile should be updated as I only changed on attribute in about key of user profile object. FYI the user profile object looks like this in my application:
{
id: 1
about: {
title: "Software Engineer",
email: "james@gmail.com",
first_name: "Duke",
last_name: "James"
},
education: [],
experience: [],
recommendations: []
}
Is it possible with context API to only update certain part of state so that it does not re-render other context consumers where change did not occur? Please help.