রেন্ডার ফাংশনের বাইরে অ্যাক্সেস প্রতিক্রিয়া প্রসঙ্গে


93

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

সুতরাং, আমি কীভাবে কেবলমাত্র একবারে আমার ক্রিয়াকে কল করতে পারি, যেমন componentDidMountরেন্ডারে কল করার পরিবর্তে?

উদাহরণস্বরূপ, এই কোডটি দেখুন:

ধরা যাক যে আমি আমার সমস্ত Providersকিছু এই উপাদানগুলিতে গুটিয়ে রেখেছি :

import React from 'react';

import UserProvider from './UserProvider';
import PostProvider from './PostProvider';

export default class Provider extends React.Component {
  render(){
    return(
      <UserProvider>
        <PostProvider>
          {this.props.children}
        </PostProvider>
      </UserProvider>
    )
  }
}

তারপরে আমি আমার সমস্ত অ্যাপ্লিকেশনটি মোড়ানো করে এই সরবরাহকারী উপাদানটি রেখেছি:

import React from 'react';
import Provider from './providers/Provider';
import { Router } from './Router';

export default class App extends React.Component {
  render() {
    const Component = Router();
    return(
      <Provider>
        <Component />
      </Provider>
    )
  }
}

এখন, উদাহরণস্বরূপ আমার ব্যবহারকারীদের দর্শনটিতে এটি এমন কিছু হবে:

import React from 'react';
import UserContext from '../contexts/UserContext';

export default class Users extends React.Component {
  render(){
    return(
      <UserContext.Consumer>
        {({getUsers, users}) => {
          getUsers();
          return(
            <h1>Users</h1>
            <ul>
              {users.map(user) => (
                <li>{user.name}</li>
              )}
            </ul>
          )
        }}
      </UserContext.Consumer>
    )
  }
}

আমি যা চাই তা হ'ল:

import React from 'react';
import UserContext from '../contexts/UserContext';

export default class Users extends React.Component {
  componentDidMount(){
    this.props.getUsers();
  }

  render(){
    return(
      <UserContext.Consumer>
        {({users}) => {
          getUsers();
          return(
            <h1>Users</h1>
            <ul>
              {users.map(user) => (
                <li>{user.name}</li>
              )}
            </ul>
          )
        }}
      </UserContext.Consumer>
    )
  }
}

তবে অবশ্যই যে উপরের উদাহরণটি কাজ করে getUsersনা কারণ আমার ব্যবহারকারীদের মধ্যে প্রপসগুলি দেখা যায় না। এটি আদৌ সম্ভব হলে এটি করার সঠিক উপায় কী?

উত্তর:


144

সম্পাদনা করুন: প্রতিক্রিয়া-আঙ্গুলসমূহ প্রবর্তনের সঙ্গে v16.8.0 , আপনি কার্মিক উপাদান মধ্যে প্রেক্ষাপটে ব্যবহার করে ব্যবহার করতে পারেন useContextহুক

const Users = () => {
    const contextValue = useContext(UserContext);
    // rest logic here
}

সম্পাদনা: 16.6.0 সংস্করণ থেকে। লাইফসাইकल পদ্ধতিতে আপনি this.contextপছন্দ মতো প্রসঙ্গ ব্যবহার করতে পারেন

class Users extends React.Component {
  componentDidMount() {
    let value = this.context;
    /* perform a side-effect at mount using the value of UserContext */
  }
  componentDidUpdate() {
    let value = this.context;
    /* ... */
  }
  componentWillUnmount() {
    let value = this.context;
    /* ... */
  }
  render() {
    let value = this.context;
    /* render something based on the value of UserContext */
  }
}
Users.contextType = UserContext; // This part is important to access context values

সংস্করণ 16.6.0 এর আগে, আপনি নিম্নলিখিত পদ্ধতিতে এটি করতে পারেন

আপনার লাইফাইল স্টাইলটিতে কনটেক্সট ব্যবহার করার জন্য আপনি নিজের উপাদানটি লিখতে চান

class Users extends React.Component {
  componentDidMount(){
    this.props.getUsers();
  }

  render(){
    const { users } = this.props;
    return(

            <h1>Users</h1>
            <ul>
              {users.map(user) => (
                <li>{user.name}</li>
              )}
            </ul>
    )
  }
}
export default props => ( <UserContext.Consumer>
        {({users, getUsers}) => {
           return <Users {...props} users={users} getUsers={getUsers} />
        }}
      </UserContext.Consumer>
)

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

import UserContext from 'path/to/UserContext';

const withUserContext = Component => {
  return props => {
    return (
      <UserContext.Consumer>
        {({users, getUsers}) => {
          return <Component {...props} users={users} getUsers={getUsers} />;
        }}
      </UserContext.Consumer>
    );
  };
};

এবং তারপরে আপনি এটি পছন্দ মতো ব্যবহার করতে পারেন

export default withUserContext(User);

এটি করার একটি উপায়! তবে আমি আমার উপাদানগুলিকে অন্যান্য স্টাফ দিয়ে মুড়িয়ে দিচ্ছি, সুতরাং কোডটি এভাবে করা আরও জটিল হবে। সুতরাং, প্রসঙ্গের লাইব্রেরিটি ব্যবহার করে এবং এটির সজ্জিতরা কোডটিকে আরও সহজ করে তোলে। তবে উত্তরের জন্য ধন্যবাদ!
গুস্তাভো মেন্ডোনিয়া

এটি আমার পক্ষে কাজ করে না, আমি প্রসঙ্গ প্রসঙ্গে গিথুবটি ব্যবহার করি
প্যাশনেট

4
শুভম খত্রি তার উত্তরে সঠিক, এটি চালানো থেকে বিরত মাত্র একটি ছোট টাইপ রয়েছে। কোঁকড়া ধনুর্বন্ধনীগুলি অন্তর্নিহিত প্রত্যাবর্তনকে আটকাচ্ছে। কেবল তাদের প্রথম বন্ধনীর সাথে প্রতিস্থাপন করুন।
ভিডিউবস

4
this.contextএকই উপাদানটির মধ্যে একাধিক প্রসঙ্গের সাথে কীভাবে ব্যবহার করবেন তা আপনি ব্যাখ্যা করতে পারেন ? ধরা যাক যে আমার কাছে এমন একটি উপাদান রয়েছে যা ইউজারকন্টেক্সট এবং পোস্ট কনটেক্সট অ্যাক্সেস করতে হবে, কীভাবে এটি পরিচালনা করতে হবে? আমি যা দেখতে পাচ্ছি তা হ'ল উভয়কেই মিশ্রিত প্রসঙ্গ তৈরি করা, তবে এটিই এর একমাত্র বা আরও ভাল সমাধান better
গুস্তাভো মেন্ডোনিয়া

4
@ গুস্তাভোমেনডোনিয়া আপনি এই কনটেক্সট এপিআই বাস্তবায়নটি ব্যবহার করে কেবল একটি একক প্রসঙ্গে সদস্যতা নিতে পারবেন। আপনার যদি
শুভম খত্রি

3

ঠিক আছে, আমি সীমাবদ্ধতার সাথে এটি করার একটি উপায় খুঁজে পেয়েছি। সঙ্গে with-contextগ্রন্থাগার আমি আমার কম্পোনেন্ট সাজসরঞ্জাম মধ্যে আমার সব ভোক্তা তথ্য সন্নিবেশ করতে পরিচালিত।

তবে, একই উপাদানটিতে একাধিক ভোক্তা সন্নিবেশ করানো জটিল, আপনাকে এই লাইব্রেরির সাথে মিশ্র ভোক্তা তৈরি করতে হবে, যা কোড মার্জিত এবং অ উত্পাদনশীল করে না।

এই লাইব্রেরির লিঙ্ক: https://github.com/SunHuawei/with-context

সম্পাদনা: আসলে আপনাকে যে মাল্টি কনটেক্সট এপিআই সরবরাহ করে তা ব্যবহার করার দরকার নেই with-context, বাস্তবে আপনি সহজ এপিআই ব্যবহার করতে পারেন এবং আপনার প্রতিটি প্রসঙ্গে ডেকরেটার তৈরি করতে পারেন এবং যদি আপনি নিজের উপাদানটিতে একাধিক গ্রাহক ব্যবহার করতে চান তবে আপনার শ্রেণীর উপরে যতটা সজ্জা আপনি চান হিসাবে ঘোষণা করুন!


1

আমার অংশ .bind(this)জন্য এটি ইভেন্ট যোগ করার জন্য যথেষ্ট ছিল । আমার উপাদানটি দেখতে কেমন লাগে।

// Stores File
class RootStore {
   //...States, etc
}
const myRootContext = React.createContext(new RootStore())
export default myRootContext;


// In Component
class MyComp extends Component {
  static contextType = myRootContext;

  doSomething() {
   console.log()
  }

  render() {
    return <button onClick={this.doSomething.bind(this)}></button>
  }
}

4
এই কোডটি অনেক সহজ দেখাচ্ছে, তবে এটি আসলে মানগুলি অ্যাক্সেস করে না বা রুটস্টোর উদাহরণের সাথে ইন্টারেক্ট করে না। আপনি দুটি ফাইল এবং প্রতিক্রিয়াশীল ইউআই আপডেট জুড়ে একটি উদাহরণ বিভক্ত করতে পারেন?
dcsan

-8

সন্তানের প্রপস হিসাবে অ্যাক্সেস পেতে আপনাকে উচ্চতর প্যারেন্ট উপাদানগুলিতে প্রসঙ্গটি পাস করতে হবে।

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