根据另一个组件更新的全局变量更新React组件

时间:2018-11-18 15:57:13

标签: javascript reactjs react-native

我有一个名为global.language的全局变量。在我的CustomHeader组件中,有一个Button用于切换语言全局变量。我想要更新所有屏幕组件以反映语言更改。

我不知道最好的方法是获取对Screens的引用或使用事件库,还是有React友好的方式来做到这一点。

我的CustomHeader.js看起来像这样:

export default class CustomHeader extends React.Component {
    constructor(props) {
        super(props);

        this.toggleLanguage = this.toggleLanguage.bind(this);
    }

    render() {
        return (
            <Button onPress={ this.toggleLanguage } title="Language" accessibilityLabel="Toggle language" />
        );
    }

    toggleLanguage() {
        if (global.language == "PT")      global.language = "EN";
        else if (global.language == "EN") global.language = "PT"; 
    }
}

我的Screen.js呈现了许多名为Event的组件。这是我的Event.js样子:

export default class Event extends React.Component {
    constructor(props) {
        super(props);
    }

    render() {
        return (
            <Card>
                <Text>{Event.getTitle(this.props.data)}</Text>
            </Card>
        );
    }

    static getTitle(data) {
        if (global.language === "PT")      return data.title;
        else if (global.language === "EN") return data.title_english;
    }
}

1 个答案:

答案 0 :(得分:1)

Live sandbox

详细信息。 React.createContext我们可以导出以重复使用。但这只是“通用”上下文。更好地将我们需要的数据和方法封装到自定义容器元素和HOC中:

import React from "react";

const context = React.createContext();
export class I18N extends React.Component {
  state = {
    language: "en"
  };

  setLanguage = language => {
    this.setState({ language });
  };

  render() {
    return (
      <context.Provider
        value={{ language: this.state.language, setLanguage: this.setLanguage }}
      >
        {this.props.children}
      </context.Provider>
    );
  }
}

export function withI18n(Component) {
  return props => (
    <context.Consumer>
      {i18nContext => <Component {...props} i18n={i18nContext} />}
    </context.Consumer>
  );
}

<I18N>是提供商,通常只会在最高级别上运行一次。 借助HOC withI18n,我们将包装需要访问我们的语言值或更新该值的功能的每个元素。

import React from "react";
import ReactDOM from "react-dom";
import { I18N, withI18n } from "./i18n";

const Header = withI18n(function({i18n}) {
  const setLang = ({ target: { value } }) => i18n.setLanguage(value);
  return (
    <div>
      <input type="radio" value="en" checked={i18n.language === "en"} onChange={setLang} /> English
      <input type="radio" value="fr" checked={i18n.language === "fr"} onChange={setLang} /> French
      <input type="radio" value="es" checked={i18n.language === "es"} onChange={setLang} /> Spanish
    </div>
  );
});

const Body = withI18n(function(props) {
  return <div>Current language is {props.i18n.language}</div>;
});

const rootElement = document.getElementById("root");
ReactDOM.render(<I18N>
  <Header />
  <Body />
</I18N>, rootElement);

最后是一篇带有其他详细信息的好文章:https://itnext.io/combining-hocs-with-the-new-reacts-context-api-9d3617dccf0b