首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >使用挂钩更新上下文状态值

使用挂钩更新上下文状态值
EN

Stack Overflow用户
提问于 2019-03-05 05:47:12
回答 2查看 2.3K关注 0票数 0

我正在尝试跟随this guide学习“如何为上下文使用基本的react钩子”,它在给上下文组件提供基本结构方面很棒,但没有深入到如何在没有返回默认值的情况下更新组件。

我正在尝试实现类似这样的东西

代码语言:javascript
复制
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>
  )
}

由于某些原因,在多次更新后返回默认值,而不是更新后的状态。我的子组件如下所示:

代码语言:javascript
复制
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>
      </>
    )
  }

我知道我做了一些错误的事情,让它调用默认值,但我不确定用什么结构来解决这个问题。

如果你有任何见解,请让我知道。

更新-(我知道值是不同的)我已经得到了我的需要,但我觉得应该有一个更干净的方式来管理它:

代码语言:javascript
复制
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>
  )
}

我希望能够动态地将未知项目添加到状态中,这就是为什么第一种方法看起来稍微好一些,但我不确定。

干杯,

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2019-03-05 06:49:15

我这样做了,它似乎起作用了:

代码语言:javascript
复制
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。

票数 0
EN

Stack Overflow用户

发布于 2019-03-05 07:24:46

看起来你已经解决了你的问题,但是我可以建议稍微修改一下吗?理想情况下(对我来说),您应该保持数据的纯净,而且我认为没有理由在其中添加update函数。

代码语言:javascript
复制
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>
    </>
  )
}
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/54992042

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档