কীভাবে কোনও সন্তানের উপাদান থেকে প্রতিক্রিয়া প্রসঙ্গে আপডেট করবেন?


98

আমার নীচের মত প্রসঙ্গে ভাষা সেটিংস রয়েছে

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জন্য নীচের মতো ভাষাটিকে 'জেপিতে' পরিবর্তন করতে প্রসঙ্গে আপডেট করতে হবে

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;

আমি কীভাবে ল্যাঙ্গুয়েজ সুইচর উপাদানটির মধ্য থেকে প্রসঙ্গটি আপডেট করতে পারি?


আপনি কি এটি পড়েছেন? ফেসবুক.
github.io/react/docs/context.html#updating-context

@azium হ্যাঁ .. সেই দস্তাবেজে প্রসঙ্গটি নিজেই উপাদানটি থেকে আপডেট করা হয়েছে বা নথিতে ব্লগের লিঙ্ক যুক্ত হয়েছে যা প্রসঙ্গ সরবরাহকারীর কাছে
প্রপস

আহ কোনও নথির প্রাসঙ্গিকতা ব্যবহার না করার কথা বলে যদি এটি আপডেট করার প্রয়োজন হয়। সুনির্দিষ্ট হতে "এটি করবেন না"। আমি পুনরাবৃত্তি করব, রাজ্য প্রসঙ্গে নয়
এজেয়াম

4
@ লন্ডনরোব আপনি কি ধরণের জবাবদিহি খুঁজছেন? আইএমও ডক্সের সামগ্রীটি আমার কাছে ঠিক সূক্ষ্ম দেখাচ্ছে। আপনি যদি কোনও সন্তানের প্রসঙ্গে সেট করতে চান তবে কেবল সরবরাহকারীর উপাদানগুলিতে একটি সেটার তৈরি করুন এবং এটি একটি শিশু ভোক্তার কাছে প্রেরণ করুন। তারপরে সেই সেটারটিকে শিশু ভোক্তায় কল করুন এবং সন্তানের মধ্যে যে কোনও ডেটা রয়েছে তা সেট করুন। এখনও ডেটা উপরে তুলে ধরার প্রতিক্রিয়াটির ধারণাটি রাখে।
অ্যান্ড্রু লি

4
@azium এই বছরগুলি পরে এই মন্তব্যটি পড়তে অন্যদের মুখোমুখি। চাইল্ড উপাদান থেকে প্রসঙ্গ আপডেট করা এখন সমর্থিত এবং বেশ সোজা: হাইপ.আইস
এমপি

উত্তর:


226

হুক ব্যবহার করা

হুকগুলি 16.8.0 এ প্রবর্তিত হয়েছিল তাই নিম্নলিখিত কোডটির ন্যূনতম সংস্করণ 16.8.0 প্রয়োজন (শ্রেণীর উপাদানগুলির উদাহরণের জন্য ডাউন স্ক্রোল করুন)। কোডস্যান্ডবক্স ডেমো

1. গতিশীল প্রসঙ্গের জন্য প্যারেন্ট রাষ্ট্র নির্ধারণ করা

প্রথমত, গতিশীল প্রসঙ্গে যা গ্রাহকদের কাছে দেওয়া যেতে পারে, আমি পিতামাতার রাজ্যটি ব্যবহার করব। এটি নিশ্চিত করে যে আমি সত্যের একক উত্স সামনে চলেছি। উদাহরণস্বরূপ, আমার প্যারেন্ট অ্যাপটি এর মতো দেখতে পাবেন:

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

  return (
    ...
  );
};

languageরাষ্ট্র মধ্যে সংরক্ষিত হয়। আমরা উভয় languageএবং সেটার ফাংশন setLanguageপরে প্রসঙ্গে হবে।

২. একটি প্রসঙ্গ তৈরি করা

এরপরে, আমি এর মতো একটি ভাষা প্রসঙ্গ তৈরি করেছি:

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

এখানে আমি language('এন') এর জন্য ডিফল্ট এবং একটি setLanguageফাংশন সেট করছি যা প্রসঙ্গ সরবরাহকারীর মাধ্যমে ভোক্তার কাছে প্রেরণ করা হবে। এগুলি কেবলমাত্র ডিফল্ট এবং প্যারেন্টে সরবরাহকারীর উপাদান ব্যবহার করার সময় আমি তাদের মানগুলি সরবরাহ করব App

দ্রষ্টব্য: LanguageContextআপনি একই কিনা

৩. প্রসঙ্গ ভোক্তা তৈরি করা

ভাষা পরিবর্তনকারীটি ভাষা সেট করার জন্য, এটি প্রসঙ্গের মাধ্যমে ভাষা সেটার ফাংশনে অ্যাক্সেস থাকা উচিত। এটি এর মতো কিছু দেখতে পারে:

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

এখানে আমি ভাষাটি 'জেপি' তে সেট করছি তবে এর জন্য ভাষা নির্ধারণ করতে আপনার নিজের যুক্তি থাকতে পারে।

৪. কোনও সরবরাহকারীকে গ্রাহককে মুড়িয়ে দেওয়া

এখন আমি আমার ভাষা পরিবর্তনকারী উপাদানটি একটিতে রেন্ডার করব 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>
  );
};

এখন, যখনই ভাষা পরিবর্তনকারী ক্লিক করা হয় এটি প্রসঙ্গটি পরিবর্তনশীলভাবে আপডেট করে।

কোডস্যান্ডবক্স ডেমো

বর্গ উপাদান ব্যবহার

সর্বশেষতম কনটেক্স এপিআই 16.3 এর প্রতিক্রিয়াতে প্রবর্তিত হয়েছিল যা গতিশীল প্রসঙ্গে থাকার দুর্দান্ত উপায় সরবরাহ করে। নিম্নলিখিত কোডটির সর্বনিম্ন সংস্করণ 16.3.0 প্রয়োজন। কোডস্যান্ডবক্স ডেমো

1. গতিশীল প্রসঙ্গের জন্য প্যারেন্ট রাষ্ট্র নির্ধারণ করা

প্রথমত, গতিশীল প্রসঙ্গে যা গ্রাহকদের কাছে দেওয়া যেতে পারে, আমি পিতামাতার রাজ্যটি ব্যবহার করব। এটি নিশ্চিত করে যে আমি সত্যের একক উত্স সামনে চলেছি। উদাহরণস্বরূপ, আমার প্যারেন্ট অ্যাপটি এর মতো দেখতে পাবেন:

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

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

  ...
}

languageএকটি ভাষা সেটার পদ্ধতি, যা আপনি রাষ্ট্র গাছ বাহিরে রাখতে পারে সহ রাষ্ট্র মধ্যে সংরক্ষিত হয়।

২. একটি প্রসঙ্গ তৈরি করা

এরপরে, আমি এর মতো একটি ভাষা প্রসঙ্গ তৈরি করেছি:

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

এখানে আমি language('এন') এর জন্য ডিফল্ট এবং একটি setLanguageফাংশন সেট করছি যা প্রসঙ্গ সরবরাহকারীর মাধ্যমে ভোক্তার কাছে প্রেরণ করা হবে। এগুলি কেবলমাত্র ডিফল্ট এবং প্যারেন্টে সরবরাহকারীর উপাদান ব্যবহার করার সময় আমি তাদের মানগুলি সরবরাহ করব App

৩. প্রসঙ্গ ভোক্তা তৈরি করা

ভাষা পরিবর্তনকারীটি ভাষা সেট করার জন্য, এটি প্রসঙ্গের মাধ্যমে ভাষা সেটার ফাংশনে অ্যাক্সেস থাকা উচিত। এটি এর মতো কিছু দেখতে পারে:

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

এখানে আমি ভাষাটি 'জেপি' তে সেট করছি তবে এর জন্য ভাষা নির্ধারণ করতে আপনার নিজের যুক্তি থাকতে পারে।

৪. কোনও সরবরাহকারীকে গ্রাহককে মুড়িয়ে দেওয়া

এখন আমি আমার ভাষা পরিবর্তনকারী উপাদানটি একটিতে রেন্ডার করব 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>
    );
  }
}

এখন, যখনই ভাষা পরিবর্তনকারী ক্লিক করা হয় এটি প্রসঙ্গটি পরিবর্তনশীলভাবে আপডেট করে।

কোডস্যান্ডবক্স ডেমো


আপনি যে ডিফল্ট মানগুলির সাথে প্রসঙ্গটি সূচনা করেন তার উদ্দেশ্য কী? এই ডিফল্টগুলি কি সর্বদা ওভাররাইড করা হয় না Provider?
ইকো

@ ইকো সঠিক, তবে যদি সরবরাহকারী পাস না করে valueতবে ডিফল্টগুলি ভোক্তার দ্বারা ব্যবহৃত হবে।
দিব্যংশু মাইথানি

4
প্রসঙ্গগুলি কেন একটি সাধারণ মান সেট / সীমাবদ্ধ করা হচ্ছে .... এটিকে খুব অদক্ষ বলে মনে হচ্ছে। এর চেয়ে আরও ভাল উদাহরণ হ'ল একটি প্রসঙ্গটি হাইলাইট করা যা কোনও অবজেক্ট হিসাবে ডিফল্ট রয়েছে এবং সেই অনুযায়ী অবজেক্টটি আপডেট করা।
অ্যালেক্সভ্যালিজো

আপনি যা উল্লেখ করছেন তার জন্য প্রসঙ্গ ব্যবহার করা সম্ভব। উত্তরের উদাহরণটি প্রশ্নের ভিত্তিতে প্রত্যাবর্তন হয়েছিল। সুতরাং, এটি বংশবৃদ্ধির জন্য কেবল একটি একক মান রয়েছে।
দিব্যংশু মাইথানি

4
টাইপস্ক্রিপ্ট আমার ক্ষেত্রে অভিযোগ করে যদি সেটল্যাঙ্গুয়েজের কোনও প্যারামিটার না থাকে। setLanguage: (language: string) => {}আমার জন্য কাজ কর.
alex351

48

মাইথানির উপরের উত্তরটি দুর্দান্ত সমাধান তবে হুক ব্যবহার না করেই এটি একটি শ্রেণি উপাদান। যেহেতু এটি কার্যকরী উপাদান এবং হুকগুলি ব্যবহার করার জন্য প্রতিক্রিয়া দ্বারা প্রস্তাবিত তাই আমি এটিকে ইউজকন্টেক্সট এবং ইউজস্টেট হুক দিয়ে প্রয়োগ করব। এখানে আপনি কীভাবে কোনও শিশু উপাদানগুলির মধ্যে থেকে প্রসঙ্গটি আপডেট করতে পারবেন।

ল্যাঙ্গুয়েজ কনটেক্সট ম্যানেজমেন্ট.জেএস

import React, { useState } from 'react'

export const LanguageContext = React.createContext({
  language: "en",
  setLanguage: () => {}
})

export const LanguageContextProvider = (props) => {

  const setLanguage = (language) => {
    setState({...state, language: language})
  }

  const initState = {
    language: "en",
    setLanguage: setLanguage
  } 

  const [state, setState] = useState(initState)

  return (
    <LanguageContext.Provider value={state}>
      {props.children}
    </LanguageContext.Provider>
  )
}

App.js

import React, { useContext } from 'react'
import { LanguageContextProvider, LanguageContext } from './LanguageContextManagement'

function App() {

  const state = useContext(LanguageContext)

  return (
    <LanguageContextProvider>
      <button onClick={() => state.setLanguage('pk')}>
        Current Language is: {state.language}
      </button>
    </LanguageContextProvider>
  )
}

export default App

4
আমি এটি করছি এবং আমার সন্তানের উপাদানগুলির মধ্যে আমার সেট ফাংশনটি সর্বদা প্রসঙ্গ তৈরি করার সময় আমরা প্রথমে ঘোষণা করেছিলাম:() => {}
আলেজান্দ্রো করিডোর

4
স্পষ্ট করে বলার জন্য, আমি মনে করি আপনার উদাহরণে state.setLanguage('pk')কিছুই করা হবে না, যেহেতু const state = useContext(LanguageContext)এর বাইরে LanguageContextProvider। আমি সরবরাহকারীর এক স্তর উপরে নিয়ে যাওয়া এবং তারপরে useContextনীচে একটি স্তরের শিশুকে ব্যবহার করে আমার সমস্যার সমাধান করেছি ।
আলেজান্দ্রো করিডোর

4
যদি আপনি আপনার কনটেক্সট প্রদানকারী এক স্তর উপরে সরানো এই মত প্রসঙ্গ ভোক্তা ব্যবহার করতে পারেন চান না যদি: <LanguageContext.Consumer> {value => /* access your value here */} </LanguageContext.Consumer>
মতিন কিণী

4
আপনি যেভাবে ল্যাঙ্গুয়েজ কনটেক্সটম্যানেজমেন্ট.জেএস ফাইলটি সাজিয়েছেন তা আমি সত্যিই পছন্দ করি। এটি আমার মতে জিনিসগুলি করার একটি পরিষ্কার উপায় এবং আমি এখনই এটি করা শুরু করব। ধন্যবাদ!
lustig

4
প্রশংসার জন্য ধন্যবাদ এটি সত্যই আমাকে এভাবে কাজ চালিয়ে যেতে উত্সাহ দেয়!
মতিন কিণী

2

একটি সহজ সরল সমাধান হ'ল আপনার প্রসঙ্গে একটি সেটস্টেট পদ্ধতি অন্তর্ভুক্ত করে আপনার প্রসঙ্গে স্টেট সেট করা:

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

এবং আপনার গ্রাহক হিসাবে, কল করুন আপডেট ভাষা যেমন:

// 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>
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.