当前位置: 首页 > 面试题库 >

如何从子组件内部更新React Context?

袁鸿畴
2023-03-14
问题内容

我在上下文中有如下语言设置

class LanguageProvider extends Component {
  static childContextTypes = {
    langConfig: PropTypes.object,
  };

  getChildContext() {
    return { langConfig: 'en' };
  }

  render() {
    return this.props.children;
  }
}

export default LanguageProvider;

我的应用程序代码如下所示

<LanguageProvider>
  <App>
    <MyPage />
  </App>
</LanguageProvider>

我的页面具有切换语言的组件

<MyPage>
  <LanguageSwitcher/>
</MyPage>

LanguageSwitcher 在这种MyPage情况下,需要更新上下文以将语言更改为“ jp”,如下所示

class LanguageSwitcher extends Component {
  static contextTypes = {
    langConfig: PropTypes.object,
  };

  updateLanguage() {
    //Here I need to update the langConfig to 'jp' 
  }

  render() {
    return <button onClick={this.updateLanguage}>Change Language</button>;
  }
}

export default LanguageSwitcher;

如何从LanguageSwitcher组件内部更新上下文?


问题答案:

挂钩是在16.8.0中引入的,因此以下代码要求最低版本为16.8.0(向下滚动以获得类组件示例)。CodeSandbox演示

1.为动态上下文设置父状态

首先,为了拥有可以传递给消费者的动态上下文,我将使用父级的状态。这样可以确保我拥有单一的真理来源。例如,我的父应用程序将如下所示:

const App = () => {
  const [language, setLanguage] = useState("en");
  const value = { language, setLanguage };

  return (
    ...
  );
};

language被存储在状态。稍后,我们将通过上下文同时传递language和setter函数setLanguage

2.创建上下文

接下来,我创建了这样的语言上下文:

// set the defaults
const LanguageContext = React.createContext({
  language: "en",
  setLanguage: () => {}
});

在这里,我为language(’en’)设置了默认值,并设置了一个setLanguage将由上下文提供程序发送给使用者的函数。这些只是默认值,在父级中使用提供程序组件时,我将提供其值App

注意:LanguageContext无论您是否保持相同

3.创建上下文使用者

为了让语言切换器设置语言,它应该可以通过上下文访问语言设置器功能。它可能看起来像这样:

const LanguageSwitcher = () => {
  const { language, setLanguage } = useContext(LanguageContext);
  return (
    <button onClick={() => setLanguage("jp")}>
      Switch Language (Current: {language})
    </button>
  );
};

在这里,我只是将语言设置为“ jp”,但是您可能有自己的逻辑来设置语言。

4.将消费者包装在提供者中

现在,我将在a中呈现语言切换器组件,LanguageContext.Provider并将必须通过上下文发送的值传递到更深的任何级别。这是我父母的App样子:

const App = () => {
  const [language, setLanguage] = useState("en");
  const value = { language, setLanguage };

  return (
    <LanguageContext.Provider value={value}>
      <h2>Current Language: {language}</h2>
      <p>Click button to change to jp</p>
      <div>
        {/* Can be nested */}
        <LanguageSwitcher />
      </div>
    </LanguageContext.Provider>
  );
};

现在,只要单击语言切换器,它就会动态更新上下文。

CodeSandbox演示

使用类组件

在React
16.3中引入了最新的上下文API,它提供了一种具有动态上下文的好方法。以下代码要求最低版本为16.3.0。CodeSandbox演示

1.为动态上下文设置父状态

首先,为了拥有可以传递给消费者的动态上下文,我将使用父级的状态。这样可以确保我拥有单一的真理来源。例如,我的父应用程序将如下所示:

class App extends Component {
  setLanguage = language => {
    this.setState({ language });
  };

  state = {
    language: "en",
    setLanguage: this.setLanguage
  };

  ...
}

language其与语言设置器方法一起存储在状态中,您可以将其保留在状态树之外。

2.创建上下文

接下来,我创建了这样的语言上下文:

// set the defaults
const LanguageContext = React.createContext({
  language: "en",
  setLanguage: () => {}
});

在这里,我为language(’en’)设置了默认值,并设置了一个setLanguage将由上下文提供程序发送给使用者的函数。这些只是默认值,在父级中使用提供程序组件时,我将提供其值App

3.创建上下文使用者

为了让语言切换器设置语言,它应该可以通过上下文访问语言设置器功能。它可能看起来像这样:

class LanguageSwitcher extends Component {
  render() {
    return (
      <LanguageContext.Consumer>
        {({ language, setLanguage }) => (
          <button onClick={() => setLanguage("jp")}>
            Switch Language (Current: {language})
          </button>
        )}
      </LanguageContext.Consumer>
    );
  }
}

在这里,我只是将语言设置为“ jp”,但是您可能有自己的逻辑来设置语言。

4.将消费者包装在提供者中

现在,我将在a中呈现语言切换器组件,LanguageContext.Provider并将必须通过上下文发送的值传递到更深的任何级别。这是我父母的App样子:

class App extends Component {
  setLanguage = language => {
    this.setState({ language });
  };

  state = {
    language: "en",
    setLanguage: this.setLanguage
  };

  render() {
    return (
      <LanguageContext.Provider value={this.state}>
        <h2>Current Language: {this.state.language}</h2>
        <p>Click button to change to jp</p>
        <div>
          {/* Can be nested */}
          <LanguageSwitcher />
        </div>
      </LanguageContext.Provider>
    );
  }
}

现在,只要单击语言切换器,它就会动态更新上下文。

CodeSandbox演示



 类似资料:
  • 我正在将父组件的状态从父组件传递到子组件。在子组件中,我有一个不同的状态。我正在对子组件的状态执行一些操作,并且结果必须添加到父组件的状态。因此,在我的父组件中,我编写了一个回调函数,该函数将更新父组件的状态。代码为: 因此,这个函数随后作为道具传递给子组件: 然后在我的子组件中,我试图实现回调函数为: 但这并没有达到预期效果。这是正确的方法吗?有人能帮我吗? 我试图通过实现这里提供的解决方案来解

  • 问题内容: 我可以更新点子管理的软件包,但是如何更新点子本身?据介绍,我目前在virtualenv中安装了pip 1.1,我想更新到最新版本。 这是什么命令?我是否需要使用distribute,或者是否有本机pip或virtualenv命令?我已经尝试过,并没有成功。 问题答案: 仅仅是一个的PyPI包像任何其他; 您可以像升级任何软件包一样使用它来升级自身: 在Windows上,推荐的命令是:

  • 假设我的父组件有两个子组件: 我从Child2获得一个输入,并将其传递给父组件(到目前为止,我知道该怎么做)。但是,我需要将该输入传递给Child1,以更新它的状态。 我怎么能那么做?

  • 问题内容: 我只需要更新,而不需要更新整个表单。我尝试使用,,,但没有人正在为我想。使用时,它正在检查不需要执行的验证。 我该如何实现? 问题答案: 首先,仅因为它根本不支持该属性,它的确不会与一起使用。也许您真的打算使用? 修复a身份后, 阅读完该答案后,您应该已经发现数据表在该特定的代码段中由标识。因此,应该采取以下所有措施: 请注意,直到PrimeFaces 3.3为止,在某些复杂的UI组合

  • 问题内容: 我开始玩vuejs(2.0)。我构建了一个包含一个组件的简单页面。该页面具有一个带有数据的Vue实例。在该页面上,我注册了该组件并将其添加到html中。该组件有一个。我希望该值反映在父对象(主Vue实例)上。 如何正确更新组件的父数据?从父级传递绑定的道具不好,并且会向控制台发出一些警告。他们的文档中有内容,但是没有用。 问题答案: Vue 2.0中不赞成使用双向绑定,而是使用事件驱动

  • 我对JS的反应有点陌生。我有两个问题。我来了 现在我要做的是,当应用程序组件挂载时,我生成一个对后端服务器的ajax调用,当它返回时,它更新道具,并设置状态,这样子组件也会重新呈现,但子组件不会重新呈现。谁能告诉我出了什么问题。 问题2 现在让我们假设我将进入组件二路由,它将呈现组件二,我在应用程序组件中生成一个ajax调用,根据ajax调用返回的数据,我在应用程序组件中设置了一些道具,我还希望组