রাজ্যহীন উপাদানগুলির কাজগুলি?


93

আমি এই শীতল <canvas>অ্যানিমেশনটি এখানে পেয়েছি একটি প্রতিক্রিয়া পুনরায় ব্যবহারযোগ্য উপাদান হিসাবে রূপান্তর করার চেষ্টা করছি । দেখে মনে হচ্ছে এই উপাদানটির জন্য ক্যানভাসের জন্য একটি প্যারেন্ট উপাদান এবং তার জন্য অনেকগুলি শিশু উপাদান প্রয়োজন function Ball()

পারফরম্যান্সের কারণে সম্ভবত এটি Ballsস্টেটলেস উপাদানগুলিতে তৈরি করা ভাল কারণ তাদের মধ্যে অনেকগুলি রয়েছে। আমি আড়ম্বরহীন উপাদান তৈরীর সাথে পরিচিত না আছি এবং হতাশ ছিল যেখানে আমি সংজ্ঞায়িত করা উচিত this.update()এবং this.drawফাংশন যে সংজ্ঞায়িত করা হয় function Ball()

রাজ্যহীন উপাদানগুলির জন্য কাজগুলি কি উপাদানটির ভিতরে বা বাইরে যায়? অন্য কথায়, নিম্নলিখিত কোনটি ভাল?

1:

const Ball = (props) => {
    const update = () => {
        ...
    }

    const draw = () => {
        ...
    }

    return (
       ...
    );
}

2:

function update() {
     ...
}

function draw() {
     ...
}

const Ball = (props) => {
    return (
       ...
    );
}

প্রত্যেকের উপকারিতা / বিভক্তিগুলি কী কী এবং যেমন খনি হিসাবে সুনির্দিষ্ট ব্যবহারের ক্ষেত্রে এর মধ্যে একটি ভাল?


আপনি কি বিদ্যমান কোডটি পোস্ট করতে পারেন যাতে আমরা দেখতে পাই যে এটি কীভাবে ব্যবহৃত হবে?
স্কিমোনস্টার

@ সিমসনস্টার আমি এটি এম্বেডড লিঙ্কে পোস্ট করেছি, সম্ভবত আপনি এটি মিস করেছেন। লিঙ্কটি এখানে: codepen.io/awendland/pen/XJExGv
মার্কসকোড

উত্তর:


117

প্রথম বিষয় লক্ষণীয় যে স্টেটলেস ফাংশনাল উপাদানগুলির পদ্ধতি থাকতে পারে না, যদি এটি স্টেটলেস ফাংশনাল উপাদান হয় তবে আপনার কলিং updateবা রেন্ডারে বিশ্বাস করা উচিত নয় ।drawBall

বেশিরভাগ ক্ষেত্রে আপনাকে উপাদান ফাংশনের বাইরে ফাংশনগুলি ডিক্লেয়ার করা উচিত যাতে আপনি সেগুলি কেবল একবার ঘোষণা করেন এবং সর্বদা একই রেফারেন্সটি পুনরায় ব্যবহার করুন। আপনি যখন ভিতরে ফাংশনটি ঘোষণা করবেন তখন প্রতিবার উপাদানটি রেন্ডার করলে ফাংশনটি আবার সংজ্ঞায়িত হবে।

এমন কিছু ক্ষেত্রে রয়েছে যেখানে আপনাকে উপাদানটির ভিতরে কোনও ফাংশন সংজ্ঞায়িত করতে হবে, উদাহরণস্বরূপ, এটি ইভেন্ট হ্যান্ডলার হিসাবে নির্ধারণ করুন যা উপাদানটির বৈশিষ্ট্যের উপর ভিত্তি করে আলাদাভাবে আচরণ করে। কিন্তু এখনও তোমাকে ফাংশন বাহিরে সংজ্ঞায়িত করতে পারে Ballএবং বাঁধুন এটা properties সহযোগে, কোড অনেক ক্লিনার তৈরীর এবং উপার্জন updateবা drawফাংশন পুনর্ব্যবহারযোগ্য।

// You can use update somewhere else
const update (propX, a, b) => { ... };

const Ball = props => (
  <Something onClick={update.bind(null, props.x)} />
);

আপনি যদি হুক ব্যবহার করছেন তবে আপনি useCallbackযখন ফাংশনটির কোনও নির্ভরতা ( props.xএই ক্ষেত্রে) পরিবর্তিত হয় কেবল তখনই ফাংশনটিকে নতুন সংজ্ঞা দেওয়া হয়েছে তা নিশ্চিত করতে আপনি ব্যবহার করতে পারেন :

const Ball = props => {
  const onClick = useCallback((a, b) => {
    // do something with a, b and props.x
  }, [props.x]);

  return (
    <Something onClick={onClick} />
  );
}

এটি ভুল উপায় :

const Ball = props => {
  function update(a, b) {
    // props.x is visible here
  }

  return (
    <Something onClick={update} />
  );
}

যখন ব্যবহার useCallback, সংজ্ঞায়িত updateফাংশন useCallbackহুক নিজেই আমাদের বাহিরে উপাদান সবকিছু বাদ দিয়েও একটি নকশা সিদ্ধান্ত হয়ে, আপনি পুনঃব্যবহারের যাচ্ছেন আপনি বিবেচনা করা উচিত updateএবং / অথবা আপনাকে কম্পোনেন্ট এর অবসান পরিধি অ্যাক্সেস করার দরকার হয়, উদাহরণস্বরূপ, পড়ুন / রাজ্যে লিখুন। ব্যক্তিগতভাবে আমি ডিফল্টরূপে এটি উপাদানটির অভ্যন্তরে সংজ্ঞায়িত করতে পছন্দ করি এবং কেবল প্রারম্ভিকভাবে ইঞ্জিনিয়ারিং রোধ করতে প্রয়োজন দেখা দেয় তবে এটি পুনরায় ব্যবহারযোগ্য করে তুলি। যে পুনরায় ব্যবহারের অ্যাপ্লিকেশন লজিক উপস্থাপনা উদ্দেশ্যে উপাদান রেখে, আরও নির্দিষ্ট হুক সঙ্গে ভাল সম্পন্ন করা হয়। হুক ব্যবহার করার সময় উপাদানটির বাইরে ফাংশনটি সংজ্ঞায়িত করা আপনার অ্যাপ্লিকেশন লজিকের জন্য আপনি যে প্রতিক্রিয়াটি চান তা থেকে ডিকউলিংয়ের গ্রেডের উপর নির্ভর করে।


ধন্যবাদ মার্কো, যা কিছুটা পরিষ্কার করে দেয়। আমার ক্ষেত্রে আমি যে বিষয়টি নিয়ে বিভ্রান্ত হয়েছি তা এর অভ্যন্তরের this.drawকার্যের সাথে সম্পর্কিত Ball। এটি ctxপিতামাতার যা হবে তা থেকে <canvas>ব্যবহার করে thisএবং সন্তানের Ballউপাদানটি কী হবে তার কীওয়ার্ডও ব্যবহার করে । রাজ্যহীন উপাদানটি কার্যকর করতে সংহত করার সর্বোত্তম উপায় কী হবে যাতে এই দুটি সম্পত্তিই অ্যাক্সেসযোগ্য?
মার্কস কোড

thisস্টেটলেস ফাংশনাল উপাদানগুলি ব্যবহার করার সময় কোনও কিছুই নেই , তা মনে রাখবেন। ক্যানভাস প্রসঙ্গে, আপনাকে এটি প্রতিটি একককে দিতে হবে Ball, এটি মোটেও ভাল লাগে না।
মার্কো স্ক্যাববিওলো

সুতরাং এক্ষেত্রে আপনার পক্ষে বলছেন এমন কোনও সন্তানের উপাদান না রাখাই ভাল?
মার্কসকোড

4
@ মার্কোস্ক্যাবিবিও না, এটি আমার ক্ষেত্রে নয়, ইতিমধ্যে বেশিরভাগ সময় ধরে স্থানীয়ভাবে তীর ফাংশন ব্যবহার করা হচ্ছে, যেহেতু একমাত্র ব্রাউজার তাদের সমর্থন করে না, তা হ'ল আই। প্রকৃতপক্ষে আমি একটি নিবন্ধ থেকে এই মন্তব্যটি সন্ধান করতে পেরেছি যেখানে এটির সত্যই দাবি করা হয়েছে যে ক্রোমেbind বিশেষত 59 এরও বেশি আগে তীর কার্যকারণের চেয়ে ধীর ছিল । এবং ফায়ারফক্সে এটি বেশ কিছুক্ষণ পরে যেহেতু তারা উভয়ই একই গতিতে সঞ্চালন করে। তাই আমি বলব যে এই জাতীয় ক্ষেত্রে পছন্দের
ভাদিম কালিনিন

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

13

স্টেটলেস ফাংশনাল উপাদানগুলির ভিতরে আমরা ফাংশন রাখতে পারি, নীচের উদাহরণটি হল:

 const Action = () => {
  function  handlePick(){
     alert("test");
  }
  return (
    <div>
      <input type="button" onClick={handlePick} value="What you want to do ?" />
    </div>
  );
}

কিন্তু, এটি একটি ভাল অনুশীলন নয় কারণ handlePick()উপাদানটি যখন ডাকা হবে তখন প্রতিবার ফাংশনটি সংজ্ঞায়িত করা হবে।


11
যদি এটি একটি ভাল অনুশীলন না হয়, তবে বিকল্প সমাধান কী হবে?
জন স্যামুয়েল

@ জনসামুয়েল বিকল্প হ'ল হ্যান্ডেলপিকটি একবারে সংজ্ঞায়িত করা হয়েছে ফলাফলের handlePick()মতো উপাদানটির উপরে / বাইরে নির্ধারণ করা বিকল্প function handlePick() { ... }; const Action = () => { ... }। আপনার যদি Actionউপাদানটি থেকে ডেটা প্রয়োজন হয় তবে আপনার এটি handlePickফাংশনের পরামিতি হিসাবে পাস করা উচিত ।
জেমস হেই

14
যদি এটি একটি ভাল অনুশীলন না হয় তবে আপনি উত্তরের সাথে ভাল অনুশীলনটি যুক্ত করতে পারতেন? এখন আমাকে আবার ভাল অনুশীলনের জন্য অনুসন্ধান করতে হবে :(
শমসির আহমাদ

2

আমরা useCallbackকার্যকারী উপাদান হিসাবে নীচে হিসাবে প্রতিক্রিয়া হুক ব্যবহার করতে পারেন :

const home = (props) => {
    const { small, img } = props
    const [currentInd, setCurrentInd] = useState(0);
    const imgArrayLength = img.length - 1;
    useEffect(() => {
        let id = setInterval(() => {
            if (currentInd < imgArrayLength) {
                setCurrentInd(currentInd => currentInd + 1)
            }
            else {
                setCurrentInd(0)
            }
        }, 5000);
        return () => clearInterval(id);
    }, [currentInd]);
    const onLeftClickHandler = useCallback(
        () => {
            if (currentInd === 0) {

            }
            else {
                setCurrentInd(currentInd => currentInd - 1)
            }
        },
        [currentInd],
    );

    const onRightClickHandler = useCallback(
        () => {
            if (currentInd < imgArrayLength) {
                setCurrentInd(currentInd => currentInd + 1)
            }
            else {

            }
        },
        [currentInd],
    );
    return (
        <Wrapper img={img[currentInd]}>
            <LeftSliderArrow className={currentInd > 0 ? "red" : 'no-red'} onClick={onLeftClickHandler}>
                <img src={Icon_dir + "chevron_left_light.png"}></img>
            </LeftSliderArrow>
            <RightSliderArrow className={currentInd < imgArrayLength ? "red" : 'no-red'} onClick={onRightClickHandler}>
                <img src={Icon_dir + "chevron_right_light.png"}></img>
            </RightSliderArrow>
        </Wrapper>);
}

export default home;

আমি তার পিতামাতার কাছ থেকে 'img' পাচ্ছি এবং এটি একটি অ্যারে।


1

আপনি যদি ফাংশনে প্রপস বা উপাদানগুলির উপাদান ব্যবহার করতে চান তবে সেটিকে ইউজক্যালব্যাক সহ সংজ্ঞায়িত করা উচিত।

function Component(props){
  const onClick=useCallback(()=>{
     // Do some things with props or state
  },[])
}

অন্যদিকে, আপনি যদি প্রপস বা ফাংশনে স্টেট ব্যবহার করতে না চান তবে উপাদানটির বাইরে এটি নির্ধারণ করুন।

const computeSomethings=()=>{
   // Do some things with params or side effects
}

function Component(props){
  
}

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