मैं React.js सीख रहा हूं और मेरे पास एक बहुत ही अजीब समस्या है। मैं ट्यूटोरियल स्टेप बाय स्टेप फॉलो करता हूं, जब मैं this.setState को कॉल करता हूं तो this.state ऑब्जेक्ट में जोक्स एरे को अपडेट करने के लिए संशोधित करता हूं, यह नहीं बदलता है। मैं चेकबॉक्स क्लिक पर completed संपत्ति को true / false पर टॉगल करना चाहता हूं। कोई कंसोल त्रुटि नहीं है।

किसी भी राय का स्वागत है।

जोक्सटेम्पलेट.जेएस

function JokeTemplate(props){

    return (
      <div className="col-md-4">
        <label>Joke {props.item.id}</label>
        <p>Question {props.item.desc}</p>
        <p>Answer: {props.item.ans}</p>
        <input type="checkbox" checked={props.item.completed} onChange={() => props.handleChange(props.item.id)} />
      </div>
    );
}

export default JokeTemplate;

चुटकुले.जेएस

import React from 'react';

import JokeTemplate from './JokeTemplate';

const jokes = [{
    id:1,
    desc: "Question 1",
    ans: "Answer 1",
    completed: false
},
{
    id:2,
    desc: "Question 2",
    ans: "Answer 2",
    completed: true
},
{
    id:3,
    desc: "Question 3",
    ans: "Answer 3",
    completed: false
}];

class Jokes extends React.Component{
    constructor(){
      super()
      this.state = {
          jokesLst: jokes
      }

      this.handleChange = this.handleChange.bind(this);
    }

    handleChange(id){

       this.setState(prevState => {
           let updatedObj = prevState.jokesLst.map( item =>{
               if(item.id === id){ 
                   item.completed = !item.completed;
               }
               return item;
           })
           
           return { jokesLst: updatedObj }
       });

    }

    render(){

        const jokesComponentArr = this.state.jokesLst.map( joke => <JokeTemplate key={joke.id} item={joke} handleChange={this.handleChange} />);

        return (
            <>
              {jokesComponentArr}
            </>
        )
    }
    
}

export default Jokes;

ऐप.जेएस

import React from 'react';
import logo from './logo.svg';
import './App.css';

import NavBar from './components/NavBar';
import Jokes from './components/Jokes';

function App() {
  
  return (
   <div className="App">
      <NavBar />
      <header className="App-header">
        <Jokes />
      </header>
    </div>
  );
}

export default App;

अग्रिम में धन्यवाद।

1
Marios Nikolaou 26 अक्टूबर 2020, 14:41

2 जवाब

सबसे बढ़िया उत्तर

ऐसा लगता है कि आपका कोड अभी भी सरणी में मूल तत्वों को संशोधित करता है क्योंकि वे ऐसी वस्तुएं हैं जिन्हें मूल्य द्वारा संदर्भित नहीं किया जाता है। समस्या को खत्म करने के लिए आपको .map() कॉल में प्रत्येक तत्व को prevState के भीतर अपने कॉलबैक में कॉपी करना होगा।

handleChange में आप इसके बजाय निम्न को आजमा सकते हैं:

this.setState(prevState => {
    let updatedObj = prevState.jokesLst.map(item => {
        const newItem = { ...item }

        if (newItem.id === id) {
           newItem.completed = !newItem .completed
        }

        return newItem
    })
          
    return { jokesLst: updatedObj }
})

ऊपर दी गई अतिरिक्त const newItem = { ...item } लाइन के साथ अंतर देखें।

या आप इसे और भी छोटा उपयोग कर सकते हैं:

this.setState(prevState => ({
   ...prevState,
   jokesLst: prevState.jokesLst.map(item => ({
      ...item,
      completed: item.id === id ? !item.completed : item.completed
   }))
})
1
norbitrial 26 अक्टूबर 2020, 14:58

मुझे लगता है कि आपको केवल जोक्स.जेएस के अंदर हैंडल चेंज () विधि में संशोधन करने की आवश्यकता है

मैंने "आइटम" को फ़िल्टर करने के लिए तर्क डालने का ऐसा तरीका कभी नहीं देखा है और इसके "पूर्ण" फ़ील्ड को this.setState() विधि के अंदर संशोधित किया है। लेकिन मैं आपको इसे इस तरह से करने का सुझाव दूंगा। तो यहाँ हम updateObj का एक नया उदाहरण बनाते हैं, पूर्ण क्षेत्र में हेरफेर करने के लिए सभी तर्क करते हैं। और फिर अंत में बस सेटस्टेट को कॉल करें और अपडेटेड ओबीजे को सीधे पास करें। मैंने कोडसैंडबॉक्स पर इसका परीक्षण किया, और यह काम करता है।

handleChange(id) {
   let updatedObj = this.state.jokesLst.map((item) => {
      if (item.id === id) {
        item.completed = !item.completed;
      }
    
      return item;
    });
    
    this.setState({
      jokesLst: updatedObj
    });
   };
0
Hendri Agustino 26 अक्टूबर 2020, 15:05