প্রতিক্রিয়া উপাদানগুলিতে পুনরায় গণনা কীভাবে বাধ্য করবেন?


110

বলি আমার কাছে একটি ভিউ উপাদান রয়েছে যা শর্তাধীন রেন্ডার রয়েছে:

render(){
    if (this.state.employed) {
        return (
            <div>
                <MyInput ref="job-title" name="job-title" />
            </div>
        );
    } else {
        return (
            <div>
                <MyInput ref="unemployment-reason" name="unemployment-reason" />
                <MyInput ref="unemployment-duration" name="unemployment-duration" />
            </div>
        );
    }
}

মাইআইনপুট এরকম কিছু দেখাচ্ছে:

class MyInput extends React.Component {

    ...

    render(){
        return (
            <div>
                <input name={this.props.name} 
                    ref="input" 
                    type="text" 
                    value={this.props.value || null}
                    onBlur={this.handleBlur.bind(this)}
                    onChange={this.handleTyping.bind(this)} />
            </div>
        );
    }
}

আসুন employedসত্য বলুন । আমি যখনই এটি মিথ্যাতে স্যুইচ করি এবং অন্যান্য ভিউ রেন্ডার হয় কেবল unemployment-durationতখনই পুনরায় আরম্ভ হয়। এছাড়াও unemployment-reasonমানটি দিয়ে প্রিফিল্ড হয় job-title(শর্ত পরিবর্তনের আগে যদি কোনও মান দেওয়া হত)।

আমি যদি দ্বিতীয় রেন্ডারিং রুটিনে মার্কআপটিকে এমন কিছুতে পরিবর্তন করি:

render(){
    if (this.state.employed) {
        return (
            <div>
                <MyInput ref="job-title" name="job-title" />
            </div>
        );
    } else {
        return (
            <div>
                <span>Diff me!</span>
                <MyInput ref="unemployment-reason" name="unemployment-reason" />
                <MyInput ref="unemployment-duration" name="unemployment-duration" />
            </div>
        );
    }
}

মনে হচ্ছে সবকিছু ঠিকঠাক কাজ করে। দেখে মনে হচ্ছে প্রতিক্রিয়া কেবলমাত্র 'চাকরি-শিরোনাম' এবং 'বেকারত্ব-কারণ' এর সাথে পৃথক হতে ব্যর্থ।

দয়া করে আমাকে বলুন আমি কী ভুল করছি ...


4
কি data-reactidপ্রতিটির MyInput(অথবা input, DOM মধ্যে দেখা) আগে ও পরে উপাদান employedসুইচ?
ক্রিস

@ ক্রিস আমি উল্লেখ করতে ব্যর্থ হয়েছি যে মাই ইনপুট-উপাদানটি ইনপুট ইনপুটটিকে রেন্ডার করে <div>data-reactidবৈশিষ্ট্যাবলী উভয় মোড়ানো div ও ইনপুট ক্ষেত্র উপর বিভিন্ন মনে করা হয়। job-titleইনপুট আইডি পায় data-reactid=".0.1.1.0.1.0.1", যখন unemployment-reasonইনপুট আইডি পায়data-reactid=".0.1.1.0.1.2.1"
o01

4
এবং কি সম্পর্কে unemployment-duration?
ক্রিস

@ ক্রিস দুঃখিত, আমি খুব শীঘ্রই কথা বলেছি। প্রথম উদাহরণে ("ডিফ আমি" স্প্যান ব্যতীত) reactidবৈশিষ্ট্যগুলি অভিন্ন job-titleএবং unemployment-reasonদ্বিতীয় উদাহরণে (ডিফ স্প্যান সহ) তারা আলাদা।
o01

জন্য @Chris অ্যাট্রিবিউট সবসময় অনন্য। unemployment-durationreactid
o01

উত্তর:


115

সম্ভবত যা ঘটছে তা হল প্রতিক্রিয়াটি মনে করে যে রেন্ডারগুলির মধ্যে কেবল একটি MyInput( unemployment-duration) যুক্ত করা হয়েছে is যেমন, job-titleকখনই এর সাথে প্রতিস্থাপিত হয় না unemployment-reason, এ কারণেই পূর্বনির্ধারিত মানগুলি অদলবদল হয়।

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

আপনি যে কোডটি সরবরাহ করেন তা শেষ কোড স্নিপেটের কারণ হ'ল প্রতিক্রিয়াটি মূলত পিতামাতার অধীনে সমস্ত উপাদানগুলির স্তরক্রম পরিবর্তন করা দরকার divএবং আমি বিশ্বাস করি যে সমস্ত বাচ্চাকে পুনরায় রেন্ডার করতে হবে (যার কারণে এটি কাজ করে)। আপনি যদি spanশীর্ষের পরিবর্তে নীচে যোগ করে থাকেন তবে পূর্ববর্তী উপাদানগুলির শ্রেণিবিন্যাস পরিবর্তন হবে না এবং সেই উপাদানগুলির পুনরায় রেন্ডার করা হবে না (এবং সমস্যাটি অব্যাহত থাকবে)।

অফিসিয়াল প্রতিক্রিয়া নথি যা বলেছিল তা এখানে :

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

প্রতিক্রিয়া কীড বাচ্চাদের সাথে পুনর্মিলন করলে, এটি নিশ্চিত করবে যে কীটি থাকা কোনও শিশু পুনরায় সাজানো হবে (ক্লোবারডের পরিবর্তে) বা ধ্বংস হবে (পুনরায় ব্যবহারের পরিবর্তে)।

keyপিতা divবা মাতা বা সমস্ত MyInputউপাদানকে নিজেই একটি অনন্য উপাদান সরবরাহ করে আপনার এটি ঠিক করতে সক্ষম হওয়া উচিত ।

উদাহরণ স্বরূপ:

render(){
    if (this.state.employed) {
        return (
            <div key="employed">
                <MyInput ref="job-title" name="job-title" />
            </div>
        );
    } else {
        return (
            <div key="notEmployed">
                <MyInput ref="unemployment-reason" name="unemployment-reason" />
                <MyInput ref="unemployment-duration" name="unemployment-duration" />
            </div>
        );
    }
}

বা

render(){
    if (this.state.employed) {
        return (
            <div>
                <MyInput key="title" ref="job-title" name="job-title" />
            </div>
        );
    } else {
        return (
            <div>
                <MyInput key="reason" ref="unemployment-reason" name="unemployment-reason" />
                <MyInput key="duration" ref="unemployment-duration" name="unemployment-duration" />
            </div>
        );
    }
}

এখন, যখন প্রতিক্রিয়াটি ভিন্ন হয়, তখন এটি দেখতে পাবে যে এটি divsআলাদা এবং এটি তার সমস্ত 'বাচ্চাদের (1 ম উদাহরণ) সহ পুনরায় রেন্ডার করবে। ২ য় উদাহরণে, পার্থক্যটি সফল হবে job-titleএবং unemployment-reasonযেহেতু তাদের কাছে এখন আলাদা কী রয়েছে।

আপনি অবশ্যই যে কোনও কীগুলি ব্যবহার করতে পারেন, যতক্ষণ না সেগুলি অনন্য থাকে।


আগস্ট 2017 আপডেট করুন

কী কী প্রতিক্রিয়াতে কাজ করে সে সম্পর্কে আরও ভাল অন্তর্দৃষ্টি করার জন্য, আমি দৃ strongly়ভাবে পরামর্শ দেব যে রিঅ্যাক্ট.জেজে অনন্য কীগুলি বোঝার জন্য আমার উত্তরটি পড়ুন


আপডেট নভেম্বর 2017

এই আপডেটটি কিছুক্ষণ আগে পোস্ট করা উচিত ছিল, তবে স্ট্রিং লিটারেলগুলি ব্যবহার refকরা এখন হ্রাস করা হয়েছে। উদাহরণস্বরূপ ref="job-title"এখন পরিবর্তে হওয়া উচিত ref={(el) => this.jobTitleRef = el}(উদাহরণস্বরূপ)। আরও তথ্যের জন্য এই.রিফগুলি ব্যবহার করে অবজ্ঞাপনের সতর্কতার আমার উত্তরটি দেখুন ।


11
it will determine which components are new and which are old based on their key property.- এটি ছিল ... আমার বোঝার মূল ...
ল্যারি

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

একটি দুর্দান্ত ইঙ্গিতটি হল একটি ডিভের কী হিসাবে একটি স্টেট ভেরিয়েবল (যা পরিবর্তিত হয়, যেমন একটি আইডির মতো)) the
ম্যাকিলিয়াস

208

উপাদানটির কীটি পরিবর্তন করুন।

<Component key="1" />
<Component key="2" />

কম্পোনেন্টটি আনমাউন্ট করা হবে এবং কীটি পরিবর্তিত হওয়ার পরে কম্পোনেন্টের একটি নতুন উদাহরণ মাউন্ট হবে।

সম্পাদনা করুন : ডকুমেন্টেড আপনার সম্পর্কে সম্ভবত উত্পন্ন রাষ্ট্রের দরকার নেই :

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


47
প্রতিক্রিয়া ডকুমেন্টেশনে এটি আরও সুস্পষ্ট হওয়া উচিত। এটি আমার পরে ঠিক কী অর্জন করেছিল, তবে এটি খুঁজতে বেশ কয়েক ঘন্টা সময় লেগেছে।
পল

4
ঠিক আছে এটি আমাকে একটি মহান চুক্তি সাহায্য করেছে! ধন্যবাদ! আমার একটি সিএসএস অ্যানিমেশন পুনরায় সেট করার দরকার ছিল তবে এটি করার একমাত্র উপায় হ'ল পুনরায় রেন্ডার করতে বাধ্য করা। আমি সম্মত হই যে প্রতিক্রিয়া নথিভুক্তিতে এটি আরও সুস্পষ্ট হওয়া উচিত
অ্যালেক্স।

@ অ্যালেক্স.পি। সুন্দর! সিএসএস অ্যানিমেশন কখনও কখনও জটিল হতে পারে। আমি একটি উদাহরণ দেখতে আগ্রহী হবে।
অ্যালেক্স কে

4
এই কৌশলটি বর্ণনা করে ডকুমেন্টেশন প্রতিক্রিয়া জানান: reactjs.org/blog/2018/06/07/…
গেমসালিউট

ধন্যবাদ. আমি এর জন্য অনেক কৃতজ্ঞ। আমি "এলোমেলো নাম্বার" এর মতো অঘোষিত প্রপসগুলিতে এলোমেলো সংখ্যা খাওয়ানোর চেষ্টা করেছি তবে কেবলমাত্র প্রপটিই কাজ করেছিল।
লজ্জাওয়্যার

5

রাষ্ট্রের সম্পত্তি setStateপরিবর্তন করতে আপনার দৃষ্টিতে ব্যবহার করুন employed। এটি প্রতিক্রিয়া রেন্ডার ইঞ্জিনের উদাহরণ।

 someFunctionWhichChangeParamEmployed(isEmployed) {
      this.setState({
          employed: isEmployed
      });
 }

 getInitialState() {
      return {
          employed: true
      }
 },

 render(){
    if (this.state.employed) {
        return (
            <div>
                <MyInput ref="job-title" name="job-title" />
            </div>
        );
    } else {
        return (
            <div>
                <span>Diff me!</span>
                <MyInput ref="unemployment-reason" name="unemployment-reason" />
                <MyInput ref="unemployment-duration" name="unemployment-duration" />
            </div>
        );
    }
}

আমি ইতিমধ্যে এটি করছি। 'নিযুক্ত' ভেরিয়েবলটি ভিউ উপাদানগুলির স্থিতির অংশ এবং এটি সেটস্টেট ফাংশনের মাধ্যমে পরিবর্তিত হয়। এটি ব্যাখ্যা না করার জন্য দুঃখিত।
o01

'নিয়োগকৃত' পরিবর্তনশীলটি প্রতিক্রিয়া রাষ্ট্রের সম্পত্তি হওয়া উচিত। এটি আপনার কোড উদাহরণে সুস্পষ্ট নয়।
দিমিত্রি

আপনি কীভাবে এটি পরিবর্তন করবেন? দয়া করে কোডটি দেখান। আপনি কি নিশ্চিত যে আপনার কোডে যথাযথ স্থানে সেটস্টেট ব্যবহার করেছেন?
দিমিত্রি

আমার উদাহরণ দেখানোর চেয়ে ভিউ উপাদানটি কিছুটা জটিল। মাই ইনপুট-উপাদানগুলি ছাড়াও, এটি একটি রেডিওবটন গ্রুপকেও উপস্থাপন করে যা একটি অনকেজ হ্যান্ডলারের সাহায্যে 'নিযুক্ত' এর মান নিয়ন্ত্রণ করে। অন ​​চেঞ্জ হ্যান্ডলারে, আমি সেই অনুযায়ী ভিউ উপাদানটির স্থিতি সেট করি। যখন রেডিওবটন গ্রুপের মান পরিবর্তন হয় তখন দৃশ্যটি পুনরায় রেন্ডার করে, তবে প্রতিক্রিয়া মনে করে যে প্রথম মাইআইনপুট উপাদানটি 'নিয়োগকৃত' পরিবর্তিত আগের মতই ছিল।
o01

0

আমি আমার অ্যাপের জন্য ক্রুডে কাজ করছি। এভাবেই আমি এটি করেছি আমার নির্ভরতা হিসাবে রেক্টসট্র্যাপটি।

import React, { useState, setState } from 'react';
import 'bootstrap/dist/css/bootstrap.min.css';
import firebase from 'firebase';
// import { LifeCrud } from '../CRUD/Crud';
import { Row, Card, Col, Button } from 'reactstrap';
import InsuranceActionInput from '../CRUD/InsuranceActionInput';

const LifeActionCreate = () => {
  let [newLifeActionLabel, setNewLifeActionLabel] = React.useState();

  const onCreate = e => {
    const db = firebase.firestore();

    db.collection('actions').add({
      label: newLifeActionLabel
    });
    alert('New Life Insurance Added');
    setNewLifeActionLabel('');
  };

  return (
    <Card style={{ padding: '15px' }}>
      <form onSubmit={onCreate}>
        <label>Name</label>
        <input
          value={newLifeActionLabel}
          onChange={e => {
            setNewLifeActionLabel(e.target.value);
          }}
          placeholder={'Name'}
        />

        <Button onClick={onCreate}>Create</Button>
      </form>
    </Card>
  );
};

কিছু সেখানে প্রতিক্রিয়া হুকস


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