当上下文值更改时防止重新渲染整个应用程序
我有一个应用程序,用户有很多个人资料信息,例如 LinkedIn 个人资料。我需要更新用户的个人资料。 我在根级别组件(即应用程序)创建一个上下文,并在多个配置文件组件中使用 useContext 挂钩共享该上下文。 用户可以从任何子组件更改个人资料属性,例如标题、个人资料摘要,并更新全局上下文。当全局上下文刷新时,它会导致使用该上下文的所有子组件重新渲染。 如何避免重新渲染没有更改的其他组件。
这是我的代码:
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;
作为我通过单击专业职称(更新状态属性的虚拟函数)来更改“关于”组件,整个应用程序重新呈现。我希望只更新配置文件的大约部分,因为我只更改了用户配置文件对象的大约键中的属性。 仅供参考,用户配置文件对象在我的应用程序中看起来像这样:
{
id: 1
about: {
title: "Software Engineer",
email: "[email protected]",
first_name: "Duke",
last_name: "James"
},
education: [],
experience: [],
recommendations: []
}
上下文 API 是否可以仅更新状态的某些部分,以便它不会重新渲染未发生更改的其他上下文使用者? 请帮忙。
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: "[email protected]",
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.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
如果任何值发生变化,上下文提供程序的任何子级都将重新渲染,解决此问题的一种方法是记住不依赖于上下文中的状态/值的组件。 您可以在此处阅读有关记忆化组件的信息。
Any child of a context provider will re-render if any of the values change, one way to go around this is by memoizing components that don't depend on the state/values in the context. You can read about memoized components here.