使用Hook更新上下文状态值
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了使用Hook更新上下文状态值相关的知识,希望对你有一定的参考价值。
我试图跟随this guide关于“如何使用基本反应钩子上下文”,它很擅长为上下文组件提供基本结构,但没有考虑如何在没有返回默认值的情况下更新片段。
我试图实现这样的事情
import React, { Component, useContext, useState } from 'react';
export const ProfileContext = React.createContext<ContextState | null>(null);
interface ContextState {
changeInformation: Function
team: string
company: string
}
export const ProfileProvider = (props) => {
const userInformation = {
company: 'Progress',
companyImage: 'https://svgshare.com/i/9ir.svg',
url: 'https://www.telerik.com/kendo-react-ui/',
userImage: 'https://i.imgur.com/Y1XRKLf.png',
userName: 'Kendoken',
fullName: 'Kendoken No Michi',
team: 'KendoReact',
// This sets all the initial values but changes the team.
// I want to make a function that changes any property by name to the new value
changeInformation: (property: string, value: any) => {
let newInfo = {...userInfo}
newInfo[property] = value
setUserInfo(newInfo);
}
}
// create `userInfo` with update method called `setUserInfo`
// set default to `userInformation`
const [userInfo, setUserInfo] = useState(userInformation);
return (
<ProfileContext.Provider value={userInfo}>
{props.children}
</ProfileContext.Provider>
)
}
出于某种原因,在多次更新后,默认值将返回而不是更新状态。我的子组件看起来像这样:
import React, { useContext } from 'react';
import { ProfileContext } from "../data"
export const ChangeTeam = () => {
const context = useContext(ProfileContext);
return (
<>
<button className="profile-button"
onClick={() => context.changeInformation('team', 'Vue')}>Vue</button>
<button className="profile-button"
onClick={() => context.changeInformation('company', 'React')}>React</button>
<p>Team: {context.team}</p>
<p>Company: {context.company}</p>
</>
)
}
我知道我做错了让它回想起默认值,但我不确定修复它的结构。
如果您有任何见解,请告诉我。
更新 - (我知道价值观是不同的)我已经得到了这个以满足我的需求,但我觉得应该有一个更清洁的方法来管理这个:
import React, { Component, useContext, useState, useEffect } from 'react';
export const ProfileContext = React.createContext<ContextState | null>(null);
interface ContextState {
setCompany: Function
setName: Function
name: string
company: string
}
export const ProfileProvider = (props: {children: htmlElement}) => {
const [company, setCompany] = useState('Progress');
const [name, setName] = useState('Bill');
return (
<ProfileContext.Provider value={{company, setCompany, name, setName}}>
{props.children}
</ProfileContext.Provider>
)
}
我希望能够动态地将未知项添加到状态,这就是为什么第一种方法似乎稍微好一点但我不确定的原因。
干杯,
答案
我做了这个似乎工作:
import React, { Component, useContext, useState, useEffect } from 'react';
export const ProfileContext = React.createContext<ContextState | null>(null);
interface ContextState {
changeInformation: Function
team: string
company: string
address: string
}
export const ProfileProvider = (props: {children: HTMLElement}) => {
const userInformation = {
company: 'Progress',
companyImage: 'https://svgshare.com/i/9ir.svg',
url: 'https://www.telerik.com/kendo-react-ui/',
userImage: 'https://i.imgur.com/Y1XRKLf.png',
userName: 'Kendoken',
fullName: 'Kendoken No Michi',
team: 'KendoReact',
// This sets all the initial values but changes the team.
// I want to make a function that changes any property by name to the new value
changeInformation: (property: string, value: any) => {
setUserInfo(prevInfo => ({
...prevInfo,
[property]: value
}) );
}
}
// create `userInfo` with update method called `setUserInfo`
// set default to `userInformation`
const [userInfo, setUserInfo] = useState(userInformation)
return (
<ProfileContext.Provider value={userInfo}>
{props.children}
</ProfileContext.Provider>
)
}
它似乎与演示完全一样,但出于某种原因,我无法让演示工作。我认为这是因为我将它设置为prevInfo。
另一答案
看起来你已经解决了你的问题,但我可以建议稍微改造一下吗?理想情况下(对我而言)你会保持你的数据纯净,我认为没有理由在那里有更新功能。
export const ProfileProvider = (props: { children: HTMLElement }) => {
const userInformation = {
company: 'Progress',
companyImage: 'https://svgshare.com/i/9ir.svg',
};
const [userInfo, setUserInfo] = useState(userInformation)
const changeInfo = (property: string, value: any) =>
setUserInfo(prevInfo => ({ ...prevInfo, [property]: value }));
return (
<ProfileContext.Provider value={{ userInfo, changeInfo }}>
{props.children}
</ProfileContext.Provider>
)
}
export const ChangeTeam = () => {
const { userInfo, changeInfo } = useContext(ProfileContext);
return (
<>
<button className="profile-button"
onClick={() => changeInfo('team', 'Vue')}>Vue</button>
<p>Team: {userInfo.team}</p>
</>
)
}
以上是关于使用Hook更新上下文状态值的主要内容,如果未能解决你的问题,请参考以下文章
使用 React useState hook 设置多个状态值
使用React useContext hook进行分派调用后,反应状态不会更新