প্রতিক্রিয়া ফর্ম লেবেলগুলির জন্য কী করে অনন্য আইডি তৈরি করবেন?


128

আমার সাথে ফর্ম উপাদান রয়েছে labelএবং আমি বৈশিষ্ট্যের labelসাথে উপাদানের সাথে লিঙ্ক করতে অনন্য আইডি রাখতে চাই htmlFor। এটার মতো কিছু:

React.createClass({
    render() {
        const id = ???;
        return (
            <label htmlFor={id}>My label</label>
            <input id={id} type="text"/>
        );
    }
});

আমি এর উপর ভিত্তি করে আইডি তৈরি করতে ব্যবহৃত হয়েছিল this._rootNodeIDতবে এটি 0.13 এর প্রতিক্রিয়া থেকে অনুপলব্ধ। এটি করার এখন সর্বোত্তম এবং / অথবা সহজ উপায় কী?


আপনি যদি এই উপাদানটি বারবার তৈরি করে থাকেন তবে আমি স্টেটমেন্টের জন্য ধরে নিচ্ছি কেন এটিতে ইটারেটর ব্যবহার করবেন না? আমি মনে করি আপনি এমন একটি ফাংশনও কল করতে পারেন যা একটি অনন্য নির্দেশিকা উত্পন্ন করে যদি কোনও সূচক সংখ্যা যথেষ্ট ভাল না হয়। stackoverflow.com/questions/105034/…
ক্রিস হকস

1
বিভিন্ন উপাদানগুলিতে অনেকগুলি বিভিন্ন ফর্ম উপাদান রয়েছে এবং তাদের সকলেরই স্বতন্ত্র আইডি থাকা উচিত। আইডি উত্পন্ন করার কাজটি হ'ল আমি কী সম্পর্কে চিন্তাভাবনা করেছি এবং যদি কেউ আরও ভাল সমাধানের পরামর্শ না দেয় তবে আমি কী করব do
আর্টেম স্যাপিগিন

3
আপনি কোথাও একটি "গ্লোবাল" ইনক্রিমেন্টিং কাউন্টার সংরক্ষণ করতে পারেন এবং এটি ব্যবহার করতে পারেন। id = 'unique' + (++GLOBAL_ID);কোথায় var GLOBAL_ID=0;?
ওয়্যার্ডপ্রাইরি

1
আমি জানি আমি খুব খুব এই পার্টিতে দেরি করে ফেলেছি, কিন্তু অন্য বিকল্প ID- র ব্যবহারের পরিবর্তে ট্যাগ ইনপুট মোড়ানো হয় যেমন:<label>My label<input type="text"/></label>
মাইক Desjardins

উত্তর:


85

এই সমাধানগুলি আমার পক্ষে ভাল কাজ করে।

utils/newid.js:

let lastId = 0;

export default function(prefix='id') {
    lastId++;
    return `${prefix}${lastId}`;
}

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

import newId from '../utils/newid';

React.createClass({
    componentWillMount() {
        this.id = newId();
    },
    render() {
        return (
            <label htmlFor={this.id}>My label</label>
            <input id={this.id} type="text"/>
        );
    }
});

তবে এটি আইসোমরফিক অ্যাপগুলিতে কাজ করবে না।

17.08.2015 যোগ করা হয়েছে । কাস্টম newId ফাংশনের পরিবর্তে আপনি লড্যাশ থেকে ইউনিক আইডি ব্যবহার করতে পারেন ।

28.01.2016 আপডেট হয়েছে । এটা আইডি জেনারেট করতে ভালো componentWillMount


3
কারণ এটি ব্রাউজারে আবার প্রথম থেকে আইডি তৈরি করা শুরু করবে। তবে আসলে আপনি সার্ভারে এবং ব্রাউজারে বিভিন্ন উপসর্গ ব্যবহার করতে পারেন।
আর্টেম স্যাপিগিন

7
এটি না render! আইডিটি তৈরি করুনcomponentWillMount
27:38 '

1
আপনি একটি রাষ্ট্রীয় ধারক তৈরি করেছেন, তবে সেটস্টেট ব্যবহার করতে অবহেলা করছেন এবং এর জন্য অনুমানটি লঙ্ঘন করছেন renderfacebook.github.io/react/docs/comp घटक-specs.html । যদিও এটি ঠিক করা বেশ সহজ হওয়া উচিত।
এআইজে

3
আমি কনস্ট্রাক্টরে লোডাশ থেকে ইউনিকআইডি ব্যবহার করছি এবং আইডি সেট করতে সেটস্টেট ব্যবহার করছি। আমার ক্লায়েন্ট শুধুমাত্র অ্যাপ্লিকেশন জন্য ভাল কাজ করে।
ক্রসপ্রোডাক্ট

1
componentWillMountঅবচয় করা হয়েছে, পরিবর্তে এটি কনস্ট্রাক্টরে করুন। দেখুন: reactjs.org/docs/react-component.html#unsafe_comp घटकwillmount
ভিক

78

আইডিটি কম্পোনেন্টওয়েলমাউন্টের (2018 এর জন্য আপডেট) ভিতরে রাখা উচিত constructor, নয় render। এটি স্থাপন করা renderঅযথা নতুন আইডি পুনরায় উত্পন্ন করবে।

আপনি যদি আন্ডারস্কোর বা লড্যাশ ব্যবহার করছেন তবে একটি uniqueIdফাংশন রয়েছে তাই আপনার ফলাফল কোডটি এমন কিছু হওয়া উচিত:

constructor(props) {
    super(props);
    this.id = _.uniqueId("prefix-");
}

render() { 
  const id = this.id;
  return (
    <div>
        <input id={id} type="checkbox" />
        <label htmlFor={id}>label</label>
    </div>
  );
}

2019 হুক আপডেট:

import React, { useState } from 'react';
import _uniqueId from 'lodash/uniqueId';

const MyComponent = (props) => {
  // id will be set once when the component initially renders, but never again
  // (unless you assigned and called the second argument of the tuple)
  const [id] = useState(_uniqueId('prefix-'));
  return (
    <div>
      <input id={id} type="checkbox" />
      <label htmlFor={id}>label</label>
    </div>
  );
}

11
অথবা আপনি এটি কনস্ট্রাক্টরের মধ্যেও রাখতে পারেন।
জন ওয়েইজ

উপাদানওয়ালমাউন্টটি ১ 16.৩.০ প্রতিক্রিয়া থেকে অবহিত করা হয়েছে, পরিবর্তে ইউএনএসএফ -২০ কম্পোনেন্টউইলমাউন্ট ব্যবহার করুন, দেখুন reactjs.org/docs/react-component.html#unsafe_compenderwillmount
লকার

2
প্রতিক্রিয়া 16.8 এ নতুন হুকগুলি দিয়ে কীভাবে এটি করা উচিত তা কি কেউ পরামর্শ দিতে পারে?
এক্সিমিলি

4
আপনি যখন আইডির মানটি অনুসরণ করছেন না, আপনি এটিও ব্যবহার করতে পারেনconst {current: id} = useRef(_uniqueId('prefix-'))
forivall

1
স্টেট ব্যবহারের পরিবর্তে ইউজারফ ব্যবহার করার সাথে তফাত কী?
এক্সপিডি

24

2019-04-04 পর্যন্ত অনুসরণ করে, এটি প্রত্যাশা হুকসের সাথে সম্পন্ন হতে সক্ষম বলে মনে হচ্ছে useState:

import React, { useState } from 'react'
import uniqueId from 'lodash/utility/uniqueId'

const Field = props => {
  const [ id ] = useState(uniqueId('myprefix-'))

  return (
    <div>
      <label htmlFor={id}>{props.label}</label>
      <input id={id} type="text"/>
    </div>
  )      
}

export default Field

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

এর মানটি idহবে myprefix-<n>যেখানে <n>থেকে একটি ইনক্রিমেন্টাল পূর্ণসংখ্যার মান ফিরে আসবে uniqueId। যদি এটি আপনার পক্ষে যথেষ্ট অনন্য না হয় তবে নিজের মতো করে বিবেচনা করুন

function gen4() {
  return Math.random().toString(16).slice(-4)
}

function simpleUniqueId(prefix) {
  return (prefix || '').concat([
    gen4(),
    gen4(),
    gen4(),
    gen4(),
    gen4(),
    gen4(),
    gen4(),
    gen4()
  ].join(''))
}

বা আমি এটির সাথে প্রকাশিত লাইব্রেরিটি এখানে দেখুন: https://github.com/rpearce/simple-uniqueid । এছাড়াও কয়েক হাজার বা হাজারো অন্যান্য অনন্য আইডি জিনিস রয়েছে, তবে লোডাশের uniqueIdএকটি উপসর্গ সহ কাজটি করার জন্য যথেষ্ট হওয়া উচিত।


2019-07-10 আপডেট করুন

হুং এইচকে অলস প্রাথমিক অবস্থার প্রতি আমাকে ইঙ্গিত করার জন্য @ হুং এইচকে ধন্যবাদ , এর যোগফলটি হ'ল আপনি useStateযে ফাংশনটি পাস করতে পারবেন তা কেবলমাত্র প্রাথমিক মাউন্টে চালানো হবে।

// before
const [ id ] = useState(uniqueId('myprefix-'))

// after
const [ id ] = useState(() => uniqueId('myprefix-'))

1
এই পৃষ্ঠায় উল্লিখিত অন্যান্য অনেক পদ্ধতির মতোই আমারও সার্ভার রেন্ডারিংয়ের ক্ষেত্রে একই সমস্যা রয়েছে: ব্রাউজারে উপাদানটি একটি নতুন আইডি দিয়ে রেন্ডার করবে।
আর্টেম স্যাপিগিন

@ আর্টেমসেপেইগিন: উপাদানগুলির অনন্য আইড রাখার কিছু উপায় নিয়ে আলোচনা করার প্রতিক্রিয়া প্রকল্পে একটি সমস্যা ( github.com/facebook/react/issues/1137 ) ছিল , তবে আমি মনে করি না যে এটির মধ্যে কিছু এসেছিল। সার্ভার এবং ক্লায়েন্টের মধ্যে উত্পন্ন আইডি একইরূপে কতটা গুরুত্বপূর্ণ? আমি একজন যে মনে হবে <input />, কি হবে ব্যাপার যে htmlForএবং idবৈশিষ্ট্যাবলী একসঙ্গে কোন ব্যাপার কি মান বাঁধা দিতে হবে।
rpearce

এটি অপ্রয়োজনীয় ডিওএম আপডেটগুলি এড়াতে গুরুত্বপূর্ণ, এটি নতুন আইডিগুলির কারণ হবে।
আর্টেম স্যাপিগিন

6
এটি ভাল যদি আপনি কোনও ক্রিয়াকলাপের পরিবর্তে initialState# 1 হিসাবে const [ id ] = useState(() => uniqueId('myprefix-'))একটি ক্রিয়াকলাপ সরবরাহ করেন # 2 const [ id ] = useState(uniqueId('myprefix-')) রাষ্ট্র: idউপরোক্ত 2 টি উপায় আলাদা নয় be তবে uniqueId('myprefix-')ভিন্নটি প্রতিটি পুনরায় রেন্ডার (# 2) এর পরিবর্তে একবার (# 1) কার্যকর করা হবে। দেখুন: অলস প্রারম্ভিক অবস্থা: reactjs.org/docs/hooks-references.html#lazy-initial-state কীভাবে অলসভাবে ব্যয়বহুল অবজেক্ট তৈরি করা যায় ?: reactjs.org/docs/…
Huong Nguyen

1
@ হুংএইচকে এটি আশ্চর্যজনক; আমি জানতাম না! আমি আমার উত্তর আপডেট করব
rpearce

4

আপনি অনন্য আইডি পেয়েছেন তা নিশ্চিত করার জন্য আপনি নোড-ইউইডের মতো লাইব্রেরি ব্যবহার করতে পারেন ।

ব্যবহার করে ইনস্টল করুন:

npm install node-uuid --save

তারপরে আপনার প্রতিক্রিয়া উপাদানটিতে নিম্নলিখিতগুলি যুক্ত করুন:

import {default as UUID} from "node-uuid";
import {default as React} from "react";

export default class MyComponent extends React.Component {   
  componentWillMount() {
    this.id = UUID.v4();
  }, 
  render() {
    return (
      <div>
        <label htmlFor={this.id}>My label</label>
        <input id={this.id} type="text"/>
      </div>
    );
  }   
}

3
অশুদ্ধ renderলঙ্ঘন facebook.github.io/react/docs/component-specs.html
aij

2
উত্তরটি অনুমানের সাথে সামঞ্জস্য করার জন্য আপডেট করা হয়েছে বলে মনে হয়
জোনাস বার্লিন

2
এটি আইসোমরফিক অ্যাপগুলিতে কাজ করে না, কারণ সার্ভারে উত্পন্ন আইডি ক্লায়েন্টের আইডি জেনারেটের চেয়ে আলাদা।
ড্যানিয়েল টি।

2
তবে এটি উত্তরের অংশ হিসাবে বলা হয়েছে, যা অত্যন্ত বিভ্রান্তিকর
টম ম্যাককেঞ্জি

1
হ্যাঁ, ইউনিভার্সালি অনন্য আইডি ব্যবহার করার জন্য -1, এটি বিশ্ব-আকারের পেরেকের জন্য একটি মহাবিশ্বের আকারের হাতুড়ি।
জন z

1

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

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

// utility to generate ids
let current = 0

export default function generateId (prefix) {
  return `${prefix || 'id'}-${current++}`
}

export function resetIdCounter () { current = 0 }

এবং তারপরে রুট কম্পোনেন্টের কনস্ট্রাক্টর বা উপাদান উইলমাউন্টে রিসেটটি কল করুন। এটি প্রতিটি সার্ভার রেন্ডারে সার্ভারের জন্য জেএস স্কোপটিকে পুনরায় সেট করে। ক্লায়েন্টে এটির কোনও প্রভাব নেই (এবং হওয়া উচিত নয়)।


যদি ক্লায়েন্টরা আবার 0 থেকে ইনপুটগুলির নামকরণ শুরু করে তবে আপনার আইডি সংঘর্ষ হতে পারে।
টমাসজ মুলারসিজিক

@ টমাসজ আপনি চান ক্লায়েন্টটি ফর্ম 0 থেকে আবার শুরু করতে যাতে চেকসামগুলি মেলে।
tenor528

0

এর সাধারণ ব্যবহারের জন্য labelএবং inputএই জাতীয় লেবেলে ইনপুট মোড়ানো কেবল সহজ:

import React from 'react'

const Field = props => (
  <label>
    <span>{props.label}</span>
    <input type="text"/>
  </label>
)      

এটি চেকবক্সগুলি / রেডিওব্লটনে শিকড় উপাদানগুলিতে প্যাডিং প্রয়োগ করা এবং ইনপুটটিতে ক্লিকের প্রতিক্রিয়া পাওয়াও সম্ভব করে তোলে।


1
সহজলভ্যতার জন্য এবং কিছু ক্ষেত্রে কার্যকর, -১ উদাহরণস্বরূপ ব্যবহারযোগ্য নয় select, বিভিন্ন পজিশনে একাধিক-লেবেল, অনুপ্রাণিত UI উপাদান ইত্যাদি etc. এছাড়াও আইডি ব্যবহারের পরামর্শ দেওয়া হয় 1111: সাধারণত, স্পষ্টত লেবেলগুলি সহায়ক প্রযুক্তি, ডাব্লু 3
মাইকেল বি।

-1

আমি এর মতো একটি সহজ সমাধান পেয়েছি:

class ToggleSwitch extends Component {
  static id;

  constructor(props) {
    super(props);

    if (typeof ToggleSwitch.id === 'undefined') {
      ToggleSwitch.id = 0;
    } else {
      ToggleSwitch.id += 1;
    }
    this.id = ToggleSwitch.id;
  }

  render() {
    return (
        <input id={`prefix-${this.id}`} />
    );
  }
}


-1

আমি একটি অনন্য আইডি জেনারেটর মডিউল তৈরি করি (টাইপস্ক্রিপ্ট):

const uniqueId = ((): ((prefix: string) => string) => {
  let counter = 0;
  return (prefix: string): string => `${prefix}${++counter}`;
})();

export default uniqueId;

এবং অনন্য আইডি উত্পন্ন করতে শীর্ষ মডিউলটি ব্যবহার করুন:

import React, { FC, ReactElement } from 'react'
import uniqueId from '../../modules/uniqueId';

const Component: FC = (): ReactElement => {
  const [inputId] = useState(uniqueId('input-'));
  return (
    <label htmlFor={inputId}>
      <span>text</span>
      <input id={inputId} type="text" />
    </label>
  );
};     

-3

আপনার প্রয়োজন না হলে আইডি ব্যবহার করবেন না, পরিবর্তে এই জাতীয় লেবেলে ইনপুটটি মোড়ানো:

<label>
   My Label
   <input type="text"/>
</label>

তারপরে আপনাকে অনন্য আইডি নিয়ে চিন্তার দরকার পড়বে না।


2
যদিও এটি এইচটিএমএল 5 দ্বারা সমর্থিত, এটি অ্যাক্সেসযোগ্যতার জন্য নিরুৎসাহিত করা হয়েছে: "এমনকি এ জাতীয় ক্ষেত্রেও, বৈশিষ্ট্যটির জন্য সেট করা ভাল অনুশীলন হিসাবে বিবেচিত হয় কারণ কিছু সহায়ক প্রযুক্তিগুলি লেবেল এবং উইজেটের মধ্যে অন্তর্নিহিত সম্পর্ক বোঝে না।" - বিকাশকারী.মোজিলা.অর্গ
মার্কিন- ডকস


1
@ ব্ল্যাকপ্লব রিএ্যাক্ট টিমের একটি অ্যাক্সেসযোগ্য ফর্ম বিভাগ রয়েছে: reactjs.org/docs/accessibility.html#accessible-forms
ভিক
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.