181

以下のようなコンテキストで言語設定があります

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 コンポーネント内からコンテキストを更新するにはどうすればよいですか?

4

4 に答える 4

7

私は個人的にこのパターンが好きです:

ファイル: context.jsx

import React from 'react';

// The Context 
const TemplateContext = React.createContext({});

// Template Provider
const TemplateProvider = ({children}) => {

    const [myValue, setMyValue] = React.useState(0);

    // Context values passed to consumer
    const value = {
        myValue,    // <------ Expose Value to Consumer
        setMyValue  // <------ Expose Setter to Consumer
    };

    return (
        <TemplateContext.Provider value={value}>
            {children}
        </TemplateContext.Provider>
    )
}

// Template Consumer
const TemplateConsumer = ({children}) => {
    return (
        <TemplateContext.Consumer>
            {(context) => {
                if (context === undefined) {
                    throw new Error('TemplateConsumer must be used within TemplateProvider');
                }
                return children(context)
            }}
        </TemplateContext.Consumer>
    )
}

// useTemplate Hook
const useTemplate = () => {
    const context = React.useContext(TemplateContext);
    if(context === undefined)
        throw new Error('useTemplate must be used within TemplateProvider');
    return context;
}

export {
    TemplateProvider,
    TemplateConsumer,
    useTemplate
}

プロバイダのツリーの子である場合は、機能コンポーネントを作成できます。

ファイル: component.jsx

import React            from 'react';
import {useTemplate}    from 'context.jsx';
const MyComponent = () => {

    // Get the value and setter from the consumer hook
    const {myValue,setMyValue} = useTemplate();

    // Demonstrate incrementing the value
    React.useEffect(()=>{
        let interval = setInterval(()=>{
            setMyValue(prev => prev + 1); // Increment, set in context
        }, 1000) // Every second
        return (
            clearInterval(interval); // Kill interval when unmounted
        )
    },[]) // On mount, no dependencies

    // Render the value as it is pulled from the context
    return (
        <React.Fragment>
            Value of MyValue is: {myValue}
        </React.Fragment>
    )
}
于 2021-07-03T13:29:21.333 に答える
4

非常に簡単な解決策の 1 つは、次のようにプロバイダーに setState メソッドを含めて、コンテキストに状態を設定することです。

return ( 
            <Context.Provider value={{
              state: this.state,
              updateLanguage: (returnVal) => {
                this.setState({
                  language: returnVal
                })
              }
            }}> 
              {this.props.children} 
            </Context.Provider>
        )

コンシューマーでは、次のように updateLanguage を呼び出します。

// button that sets language config
<Context.Consumer>
{(context) => 
  <button onClick={context.updateLanguage({language})}> 
    Set to {language} // if you have a dynamic val for language
  </button>
<Context.Consumer>
于 2020-01-28T06:58:25.617 に答える