আমি কীভাবে প্রতিক্রিয়ার "যদি" উপাদানটি টাইপস্ক্রিপ্টে বাস্তব "যদি" এর মতো কাজ করে তা করতে পারি?


11

আমি <If />প্রতিক্রিয়াটি ব্যবহার করে একটি সাধারণ ফাংশন উপাদান তৈরি করেছি :

import React, { ReactElement } from "react";

interface Props {
    condition: boolean;
    comment?: any;
}

export function If(props: React.PropsWithChildren<Props>): ReactElement | null {
    if (props.condition) {
        return <>{props.children}</>;
    }

    return null;
}

এটি আমাকে একটি ক্লিনার কোড লিখতে দেয়, যেমন:

render() {

    ...
    <If condition={truthy}>
       presnet if truthy
    </If>
    ...

বেশিরভাগ ক্ষেত্রে, এটি ভাল কাজ করে, তবে যখন আমি উদাহরণস্বরূপ পরীক্ষা করতে চাই যদি প্রদত্ত ভেরিয়েবলটি সংজ্ঞায়িত না করা হয় এবং তারপরে এটি সম্পত্তি হিসাবে পাস করা হয় তবে এটি একটি ইস্যুতে পরিণত হয়। আমি একটি উদাহরণ দেব:

ধরা যাক আমার কাছে একটি উপাদান <Animal />রয়েছে যার মধ্যে নিম্নলিখিত প্রপস রয়েছে:

interface AnimalProps {
  animal: Animal;
}

এবং এখন আমার কাছে আরও একটি উপাদান রয়েছে যা নিম্নলিখিত ডোমকে রেন্ডার করে:

const animal: Animal | undefined = ...;

return (
  <If condition={animal !== undefined} comment="if animal is defined, then present it">
    <Animal animal={animal} /> // <-- Error! expected Animal, but got Animal | undefined
  </If>
);

আমি যেমন মন্তব্য করেছি, প্রকৃতপক্ষে প্রাণীটিকে সংজ্ঞায়িত করা হয়নি, টাইপসক্রিপ্টটি বলার উপায় নেই যে আমি ইতিমধ্যে এটি পরীক্ষা করে ফেলেছি। animal!কাজ করার জন্য দৃser়তার দাবি , তবে এটি আমি খুঁজছি না।

কোন ধারনা?


1
নিশ্চিত নন যে টাইপস্ক্রিপ্টে তাকে বলা আপনার পক্ষে ইতিমধ্যে নাল সুরক্ষাটি চেচ করা সম্ভব। সম্ভবত {animal !== undefined && <Anibal animal={animal} />}কাজ করবে
অলিভিয়ার বোইস

1
এটি ingালাই কাজ করে না? <Animal animal={animal as Animal} />
পল

@ OlivierBoissé আমি যে বাক্য গঠন ব্যবহারের সীমাবদ্ধ করছি
Eliya কোহেন

@ পল হ্যাঁ, তবে ""! শেষে?
এলিয়া কোহেন

উত্তর:


3

এটা অসম্ভব বলে মনে হচ্ছে।

কারণ: আমরা পরিবর্তন Ifউপাদান এর বিষয়বস্তু থেকে

if (props.condition) {
  ...
}

এর বিপরীতে

if (!props.condition) {
  ...
}

আপনি খুঁজে পাবেন যে এবার আপনি বিবিধ উপায়ে প্রকারটি প্রক্রিয়াকরণ করতে চান।

  <If condition={animal === undefined} comment="if animal is defined, then present it">
    <Animal animal={animal} /> // <-- Error! expected Animal, but got Animal | undefined
  </If>

যার অর্থ এটি স্বাধীন নয়, এই সিদ্ধান্তে পৌঁছায় যে দুটি অবস্থার একটিরও স্পর্শ না করে এই অবস্থায় এই ধরণের আলাদা করা সম্ভব নয়।


আমি নিশ্চিত না যে সেরা পদ্ধতির কী, তবে এখানে আমার চিন্তার একটি is

আপনি সংজ্ঞায়িত পারে Animal component'র সাজসরঞ্জাম animalটাইপ করা বিষয় এর সঙ্গে
বিভাজক শর্তসাপেক্ষ ধরনের : NonNullable

দলিল

type T34 = NonNullable<string | number | undefined>;  // string | number

ব্যবহার

interface AnimalProps {
  // Before
  animal: Animal;
  // After
  animal: NonNullable<Animal>;
}

এটা তোলে দ্বারা উত্পন্ন না Ifকম্পোনেন্ট অবস্থার কিন্তু যেহেতু আপনি শুধুমাত্র ব্যবহার child componentভিতরে যে অবস্থা, এটি ডিজাইন কিছু জ্ঞান করে তোলে child componentযেমন এর সাজসরঞ্জাম none nullable, এই শর্তে যে অধীনে

টাইপ Animalকরে থাকে undefined


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

@ এলিয়াকোহেন আপডেট হয়েছে, এই উত্তরের জন্য কিছু সংযোজন করা দরকার?
কেইকাই

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

1

সংক্ষিপ্ত উত্তর?

আপনি পারবেন না।

যেহেতু আপনি animalহিসাবে সংজ্ঞায়িত করেছেন Animal | undefined, অপসারণের একমাত্র উপায় undefinedহ'ল হয় কোনও প্রহরী তৈরি করা বা animalঅন্য কিছু হিসাবে পুনঃস্থাপন করা। তুমি তোমার শর্ত সম্পত্তি টাইপ পাহারা গোপন করেছি, এবং তাই এটি জানতে পারে না আপনার মধ্যে বেছে নিচ্ছেন টাইপ করা বিষয়, বুদ্ধিমান সেখানে কি ঘটছে তা কোন উপায় আছে Animalএবং undefined। আপনার এটি castালাই বা ব্যবহার করতে হবে !

যদিও বিবেচনা করুন: এটি ক্লিনার মনে হতে পারে তবে এটি কোডের একটি অংশ তৈরি করে যা বোঝার এবং বজায় রাখা দরকার, সম্ভবত অন্য কেউ লাইনটির নিচে। সংক্ষেপে আপনি একটি নতুন ভাষা তৈরি করছেন, প্রতিক্রিয়া উপাদানগুলি দিয়ে তৈরি, যা টাইপস্ক্রিপ্ট ছাড়াও কারও শেখার প্রয়োজন হবে।

শর্তসাপেক্ষে জেএসএক্স আউটপুট দেওয়ার একটি বিকল্প পদ্ধতি হ'ল renderআপনার শর্তযুক্ত সামগ্রী যেমন ভেরিয়েবলগুলি নির্ধারণ করা

render() {
  const conditionalComponent = condition ? <Component/> : null;

  return (
    <Zoo>
      { conditionalComponent }
    </Zoo>
  );
}

এটি এমন একটি স্ট্যান্ডার্ড অ্যাপ্রোচ যা অন্যান্য বিকাশকারীরা তাত্ক্ষণিকভাবে স্বীকৃত হবে এবং তাকাতে হবে না।


0

একটি রেন্ডার কলব্যাক ব্যবহার করে, আমি টাইপ করতে সক্ষম হলাম যে রিটার্ন প্যারামিটারটি ছোট নয়।

আমি আপনার আসল Ifউপাদানটি সংশোধন করতে পারছি না কারণ আমি জানি না যে আপনার conditionদাবী কী এবং এটিতে কী পরিবর্তনশীল ascondition={animal !== undefined || true}

দুর্ভাগ্যক্রমে, আমি এই কেসটি IsDefinedপরিচালনা করার জন্য একটি নতুন উপাদান তৈরি করেছি :

interface IsDefinedProps<T> {
  check: T;
  children: (defined: NonNullable<T>) => JSX.Element;
}

function nonNullable<T>(value: T): value is NonNullable<T> {
  return value !== undefined || value !== null;
}

function IsDefined({ children, check }: IsDefinedProps<T>) {
  return nonNullable(check) ? children(check) : null;
}

childrenএটি একটি কলব্যাক হবে তা ইঙ্গিত করে , যা টাইপ টির একটি নন-ন্যাবেল পাস হবে যা একই ধরণের check

এটির সাহায্যে আমরা একটি রেন্ডার কলব্যাক পাব, যা নাল-চেক করা ভেরিয়েবলটি পাস হবে।

  const aDefined: string | undefined = mapping.a;
  const bUndefined: string | undefined = mapping.b;

  return (
    <div className="App">
      <IsDefined check={aDefined}>
        {aDefined => <DoSomething message={aDefined} />} // is defined and renders
      </IsDefined>
      <IsDefined check={bUndefined}>
        {bUndefined => <DoSomething message={bUndefined} />} // is undefined and doesn't render
      </IsDefined>
    </div>
  );

আমার এখানে একটি কার্যকারী উদাহরণ রয়েছে https://codesandbox.io/s/blazing-pine-2t4sm


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