रिएक्ट हुक में पुश विधि (useState)?


124

कैसे उपयोग करने के लिए तत्व अंदर धक्का सरणी सरणी प्रतिक्रिया हुक? प्रतिक्रिया अवस्था में क्या यह पुरानी पद्धति है? या कुछ नया?

उदाहरण setState पुश उदाहरण ?

जवाबों:


311

जब आप उपयोग करते हैं useState, तो आप राज्य मद के लिए एक अपडेट विधि प्राप्त कर सकते हैं:

const [theArray, setTheArray] = useState(initialArray);

फिर, जब आप एक नया तत्व जोड़ना चाहते हैं, तो आप उस फ़ंक्शन का उपयोग करते हैं और नए सरणी या एक फ़ंक्शन में पास होते हैं जो नए सरणी का निर्माण करेगा। आम तौर पर बाद वाले, चूंकि राज्य अपडेट अतुल्यकालिक हैं और कभी-कभी बैचेड होते हैं:

setTheArray(oldArray => [...oldArray, newElement]);

कभी-कभी आप उस कॉलबैक फॉर्म का उपयोग किए बिना दूर हो सकते हैं, यदि आप केवल कुछ विशिष्ट उपयोगकर्ता घटनाओं के लिए हैंडलर में सरणी को अपडेट करते हैं, जैसे click(लेकिन इस तरह mousemove):

setTheArray([...theArray, newElement]);

जिन घटनाओं के लिए रिएक्ट सुनिश्चित करता है कि रेंडरिंग को फ्लश किया जाता है वे यहां सूचीबद्ध "असतत घटनाएं" हैं

लाइव उदाहरण (कॉलबैक में पास करना setTheArray):

क्योंकि एक ही घटना theArrayमें एक अद्यतन click(एक "असतत" घटनाओं में से एक) है, मैं इसमें प्रत्यक्ष रूप से भाग सकता हूं addEntry:


1
... और कोशिश करें setTheArray(currentArray => [...currentArray, newElement])कि ऊपर वाला काम न करे। सबसे अधिक संभावना है useEffect(...theArray..., []), यह महसूस करना महत्वपूर्ण है कि theArrayयह एक स्थिर है, इसलिए भविष्य के
रेंडरर्स के

@ एप्रिलीन - निश्चित नहीं कि आप उस useEffectउदाहरण के साथ क्या कह रहे हैं ...?
टीजे क्राउडर

1
यदि useEffectकोई खाली निर्भरता सूची है [], तो उसे पहले रेंडर के दौरान ही निष्पादित किया जाएगा। तो theArrayप्रभाव के अंदर का मूल्य हमेशा रहेगा initialArray। उन स्थितियों में जहां setTheArray([...initialArray, newElement])कोई मतलब नहीं होगा, और जब theArrayनिरंतर हमेशा के बराबर होगा initialValue, तो कार्यात्मक अपडेट की आवश्यकता होती है।
अप्रैल

@ एप्रिलियन - मुझे डर है कि मैं अभी भी इसे प्राप्त नहीं कर रहा हूं, संभवतः थोड़ा घना हो रहा हूं। :-) आपको केवल प्रारंभिक सरणी मान के साथ एक प्रभाव की आवश्यकता क्यों होगी ? (मेरा मतलब है, एक असीम उपयोग का मामला हो सकता है, लेकिन ...) और यहां तक ​​कि अगर आप करते हैं, तो सवाल के साथ क्या करना है?
टीजे क्राउडर

1
यार, मैं सबसे लंबे समय तक इससे जूझता रहा। मैंने सोचा था setTheArray(()=>theArray.concat(newElement))कि काम करेगा, लेकिन नहीं! कॉलबैक का वह पैरामीटर सभी को अलग बनाता है।
जेफ लोरी

52

थोड़ा और विस्तार करने के लिए, यहां कुछ सामान्य उदाहरण दिए गए हैं। के साथ शुरू:

const [theArray, setTheArray] = useState(initialArray);
const [theObject, setTheObject] = useState(initialObject);

सरणी के अंत में तत्व पुश करें

setTheArray(prevArray => [...prevArray, newValue])

ऑब्जेक्ट के अंत में पुश / अपडेट तत्व

setTheObject(prevState => ({ ...prevState, currentOrNewKey: newValue}));

ऑब्जेक्ट की सरणी के अंत में पुश / अपडेट तत्व

setTheArray(prevState => [...prevState, {currentOrNewKey: newValue}]);

सरणियों की वस्तु के अंत में पुश तत्व

let specificArrayInObject = theObject.array.slice();
specificArrayInObject.push(newValue);
const newObj = { ...theObject, [event.target.name]: specificArrayInObject };
theObject(newObj);

यहाँ कुछ काम करने के उदाहरण भी दिए गए हैं। https://codesandbox.io/s/reacthooks-push-r991u


5
सभी उदाहरणों के लिए धन्यवाद। सटीक बात मैं के साथ एक मुद्दा था arrays की वस्तु के अंत में अपने पुश तत्व था । मैंने कई अलग-अलग चीजों की कोशिश की, लेकिन बस इसे एक साथ नहीं कर सकते।
sdouble

1
प्रिस्टेट के उपयोग ने मेरी समस्या को ठीक कर दिया कि केवल अंतिम कॉल को एक साथ सरणी कॉन्फैट और फिल्टर पर लागू किया जा रहा था।
हेनरिक ब्रूनो

5

उसी तरह से आप इसे रिएक्ट क्लास के घटकों में "सामान्य" स्थिति के साथ करते हैं।

उदाहरण:

function App() {
  const [state, setState] = useState([]);

  return (
    <div>
      <p>You clicked {state.join(" and ")}</p>
      //destructuring
      <button onClick={() => setState([...state, "again"])}>Click me</button>
      //old way
      <button onClick={() => setState(state.concat("again"))}>Click me</button>
    </div>
  );
}

1
यह onClick के साथ काम करेगा, लेकिन setState (oldState => [... oldState, pushsomething]) है कि आपको यह कैसे करना चाहिए
साइरस ज़ी

3
// Save search term state to React Hooks with spread operator and wrapper function

// Using .concat(), no wrapper function (not recommended)
setSearches(searches.concat(query))

// Using .concat(), wrapper function (recommended)
setSearches(searches => searches.concat(query))

// Spread operator, no wrapper function (not recommended)
setSearches([...searches, query])

// Spread operator, wrapper function (recommended)
setSearches(searches => [...searches, query])

https://medium.com/javascript-in-plain-english/how-to-add-to-an-array-in-react-state-3d08ddb2e1dc


2

setTheArray([...theArray, newElement]);सबसे सरल उत्तर है, लेकिन ऐरे में वस्तुओं के उत्परिवर्तन के लिए सावधान रहें । सरणी आइटम की गहरी क्लोनिंग का उपयोग करें।


आप जिस गहरी क्लोनिंग का उल्लेख करते हैं, उसका मतलब है कि यह ओब्जा के रूप में प्राप्त होता है। UseState और objA को objB के साथ संक्षिप्त करें? इसी कड़ी के रूप में? gist.githubusercontent.com/kahsing/…
Luiey

1

अधिकांश अनुशंसित विधि आवरण फ़ंक्शन और प्रसार ऑपरेटर का एक साथ उपयोग कर रही है। उदाहरण के लिए, यदि आपने किसी राज्य को nameइस तरह से शुरू किया है,

const [names, setNames] = useState([])

आप इस सरणी को इस तरह धकेल सकते हैं,

setNames(names => [...names, newName])

उम्मीद है की वो मदद करदे।


कृपया लिंक केवल उत्तर पोस्ट न करें। भविष्य में लिंक को तोड़ा जा सकता है। इसके बजाय, उस लेख का एक राइट-अप बनाएं और वास्तव में प्रश्न का उत्तर देना सुनिश्चित करें।
ब्लैकचिटा

हालांकि यह लिंक प्रश्न का उत्तर दे सकता है, लेकिन उत्तर के आवश्यक भागों को शामिल करना और संदर्भ के लिए लिंक प्रदान करना बेहतर है। लिंक-केवल उत्तर अमान्य हो सकते हैं यदि लिंक किए गए पृष्ठ बदल जाते हैं। - समीक्षा से
ilke444

1

यदि आप विशिष्ट सूचकांक के बाद पुश करना चाहते हैं तो आप नीचे बता सकते हैं:

   const handleAddAfterIndex = index => {
       setTheArray(oldItems => {
            const copyItems = [...oldItems];
            const finalItems = [];
            for (let i = 0; i < copyItems.length; i += 1) {
                if (i === index) {
                    finalItems.push(copyItems[i]);
                    finalItems.push(newItem);
                } else {
                    finalItems.push(copyItems[i]);
                }
            }
            return finalItems;
        });
    };

1

आप कस्टम राज्य के अंत में डेटा की सरणी जोड़ सकते हैं:

  const [vehicleData, setVehicleData] = React.useState<any[]>([]);
  setVehicleData(old => [...old, ...newArrayData]);

उदाहरण के लिए, नीचे में, आप अक्षतंतु का एक उदाहरण दिखाई देते हैं:

  useEffect(() => {
    const fetchData = async () => {
      const result = await axios(
        {
          url: `http://localhost:4000/api/vehicle?page=${page + 1}&pageSize=10`,
          method: 'get',
        }
      );
      setVehicleData(old => [...old, ...result.data.data]);
    };

    fetchData();
  }, [page]);

0

मैंने उपयोग करने के लिए ऑब्जेक्ट के एक सरणी में ऑब्जेक्ट पुश करने के लिए उपरोक्त विधियों की कोशिश की, लेकिन टाइपस्क्रिप्ट का उपयोग करते समय निम्न त्रुटि हुई :

टाइप करें 'TxBacklog [] | अपरिभाषित 'के पास एक' सिम्बॉल.इटरेटर 'पद्धति होनी चाहिए जो एक itter.ts (2488) लौटाती है

Tsconfig.json के लिए सेटअप स्पष्ट रूप से सही था:

{
   "compilerOptions": {
   "target": "es6",
   "lib": [
      "dom",
      "dom.iterable",
      "esnext",
      "es6",
],

इस समाधान ने समस्या को हल कर दिया (मेरा नमूना कोड):

इंटरफेस:

   interface TxBacklog {
      status: string,
      txHash: string,
   }

अवस्था चर:

    const [txBacklog, setTxBacklog] = React.useState<TxBacklog[]>();

नई वस्तु को सरणी में रखें:

    // Define new object to be added
    const newTx = {
       txHash: '0x368eb7269eb88ba86..',
       status: 'pending'
    };
    // Push new object into array
    (txBacklog) 
       ? setTxBacklog(prevState => [ ...prevState!, newTx ])
       : setTxBacklog([newTx]);
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.