2017-12-28 170 views
6

मैं बटन पर क्लिक भेजने पर एक से अधिक रेडियो बटन समूहों से चयनित रेडियो बटन id की सूची भेजने के लिए कोशिश कर रहा हूँ,प्रतिक्रियाओं में एक घटक में एकाधिक रेडियो बटन समूहों को कैसे संभालें?

मेरे समस्या: मैं बैकएंड से चयनित रेडियो बटन हो रही है, तो मैं बदलने के लिए सक्षम होना चाहिए रेडियो बटन और बैकएंड पर वापस भेजें। लेकिन जब मैं रेडियो बटन बदलने की कोशिश करता हूं तो यह काम नहीं कर रहा है।

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

wireframe

function CardsList(props) { 
 
    const cards = props.cards; 
 
    return (
 
    <div> 
 
     {cards.map((card, idx) => (
 
     <div> 
 
     {card.cardName} 
 
      { 
 
      card.options.map((lo,idx) => (
 
       <li key={idx}> 
 
       <input 
 
       className="default" 
 
       type="radio" 
 
       name={card.cardName} 
 
       checked={lo.selected} 
 
      />)) 
 
      } 
 
     <div> 
 
     ))} 
 
    </div> 
 
); 
 
} 
 
//array of cards coming from the backend 
 
const cards = [ 
 
{cardName:'card1',options:[{radioName:'card1-radio1',selected:'true'}, 
 
          {radioName:'card1-radio2',selected:'false'}]}, 
 
    {cardName:'card2',options:[{radioName:'card2-radio1',selected:'true'}, 
 
          {radioName:'card2-radio2',selected:'false'}]} 
 
]; 
 
ReactDOM.render(
 
    <CardsList cards={cards} />, 
 
    document.getElementById('root') 
 
);
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script> 
 
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script> 
 
<div id="root"></div>

उत्तर

0

कारण आप उन्हें क्यों नहीं बदल सकते है, क्योंकि उनके मौजूदा जाँच की राज्य की जो आप सेट कर रहे हैं:

यहाँ wireframe और कोड स्निपेट है यहां:

<input 
    className="default" 
    type="radio" 
    name={card.cardName} 
    checked={lo.selected} 
/> 

इस सटीक परिदृश्य के लिए मैंने जिस दृष्टिकोण का उपयोग किया है, वह घटक के राज्य (सर्वर से) को मेरे घटक के राज्य (this.state) में संग्रहीत कर रहा है, जिससे राज्य को तत्व पास किया जा रहा है: checked={this.state.isChecked}, और तत्व की स्थिति onClick अद्यतन करना।

उदाहरण:

class CardsList extends Component { 
    constructor(props){ 
    super(props); 
    this.state = {isChecked: false}; 
    this.inputOnClick = this.inputOnClick.bind(this); 
    } 
    //fetch data from server 
    fetchData(){ 
    fetch('/api') 
     .then(res => res.json()) 
     //this will be our initial state 
     .then(res => this.setState(res)) 
    } 
    componentDidMount(){ 
    this.fetchData(); 
    } 
    //change radio button state on click 
    inputOnClick(e){ 
    e.preventDefault(); 
    //invert state value 
    this.setState((prevState, props) => {isChecked: !prevState.isChecked}); 
    } 
    render(){ 
    return (
     <input 
     type="radio" 
     checked={this.state.isChecked} 
     onClick={this.inputOnClick} 
     /> 
    ) 
    } 
} 

इस जवाब एक रेडियो बटन समूह के साथ काम कर सकते हैं, लेकिन मैं कई रेडियो बटन में के साथ कई रेडियो बटन के साथ समस्या का सामना कर रहा हूँ groups.If आप ताश के पत्तों की श्रृंखला दिखाई देगी , यह कैसे पता चलता है कि कौन सा रेडियो बटन समूह से संबंधित है।

हम रेडियो बटन के नाम के आधार पर राज्य को संशोधित कर सकते हैं।

चलो अपने सभी कार्ड को अपने घटक के राज्य में सहेजें। मुझे पता है कि कार्ड सर्वर से पुनर्प्राप्त किए गए हैं और setState का उपयोग करके सहेजा जाएगा लेकिन मैं इसे दृश्य उद्देश्यों के लिए इस तरह लिख रहा हूं।

this.state = {cards: [ 
    { cardName:'card1', 
    options:[ 
    {radioName:'card1-radio1',selected:true}, 
    {radioName:'card1-radio2',selected:false} 
    ] 
    }, 
    { cardName:'card2', 
    options:[ 
     {radioName:'card2-radio1',selected:true}, 
     {radioName:'card2-radio2',selected:false} 
    ] 
    } 
]} 

अब जब हम रेडियो बटन पर क्लिक करते हैं, तो हम उस रेडियो बटन का नाम उस राज्य को अपडेट करने के लिए करेंगे जहां इसे अद्यतन करने की आवश्यकता है। चूंकि प्रतिक्रिया राज्य को अपरिवर्तनीय होने की आवश्यकता है, इसलिए हम राज्य की गहरी प्रतिलिपि बनायेंगे, इसे संशोधित करेंगे, और उसके बाद राज्य को स्थापित करेंगे।

inputOnClick(e){ 
    e.preventDefault(); 
    var thisRadioBtn = e.target.name; 
    //make a deep copy of the state 
    const stateCopy = JSON.parse(JSON.stringify(this.state.cards)); 
    //go through state copy and update it 
    stateCopy.forEach(card => { 
    card.options.forEach(option => { 
     if(option.radioName === thisRadioBtn){ 
     //invert value 
     //make sure the values are booleans 
     option.selected = !option.selected; 
     } 
    }); 
    }); 
    //update the components state 
    this.setState({cards: stateCopy}); 
} 
+0

इस जवाब मीटर एई एक रेडियो बटन समूह के साथ काम करता है, लेकिन मुझे कई रेडियो बटन समूहों के साथ कई रेडियो बटनों के साथ समस्या का सामना करना पड़ रहा है। अगर आप कार्ड की सरणी देखते हैं, तो यह कैसे पता चलता है कि यह कौन सा रेडियो बटन समूह है। – user8208248

+0

@ user8208248 मेरा नया संपादन –

+0

देखें यदि हमारे पास गतिशील स्थिति है और हम नहीं जानते कि बैकएंड से कितने कार्ड प्राप्त होंगे? मैं अपने अंत में कोशिश कर रहा हूं। एक बार मैं एकदम सही पाने के बाद शायद मैं पोस्ट करूंगा। – user8208248

0

आप किसी ऑब्जेक्ट को लुकअप टेबल के रूप में उपयोग कर सकते हैं जिसमें समूह के नाम कुंजी के रूप में होते हैं।
प्रत्येक परिवर्तन पर आपको प्रासंगिक विकल्प के साथ प्रासंगिक समूह को ढूंढने और तदनुसार नया राज्य सेट करने की आवश्यकता होगी।

महत्वपूर्ण! - यहां ध्यान देने योग्य एक बात यह है कि मैंने selected संपत्ति String से Boolean पर बदल दी है। इस मुझे इस तरह की स्थिति को संभाल करने देगा:

<input checked={option.selected} /> 

आप एक Boolean करने के लिए इसे बदल नहीं सकते हैं तो आप इस तरह की हालत को संभालने के लिए की आवश्यकता होगी:

<input checked={option.selected === 'true'} /> 

यहाँ एक चल उदाहरण है :

//array of cards coming from the backend 
 
const data = [ 
 
    { 
 
    cardName: 'card1', options: [{ radioName: 'card1-radio1', selected: true }, 
 
    { radioName: 'card1-radio2', selected: false }] 
 
    }, 
 
    { 
 
    cardName: 'card2', options: [{ radioName: 'card2-radio1', selected: true }, 
 
    { radioName: 'card2-radio2', selected: false }] 
 
    } 
 
]; 
 

 

 
class CardsList extends React.Component { 
 
    constructor(props) { 
 
    super(props); 
 
    this.state = { 
 
     cards: [] 
 
    }; 
 
    } 
 

 
    componentDidMount() { 
 
    setTimeout(() => { 
 
     // mimic an async server call 
 
     this.setState({ cards: data }); 
 
    }, 1000); 
 
    } 
 

 
    onInputChange = ({ target }) => { 
 
    const { cards } = this.state; 
 
    const nexState = cards.map(card => { 
 
     if (card.cardName !== target.name) return card; 
 
     return { 
 
     ...card, 
 
     options: card.options.map(opt => { 
 
      const checked = opt.radioName === target.value; 
 
      return { 
 
      ...opt, 
 
      selected: checked 
 
      } 
 
     }) 
 
     } 
 
    }); 
 
    this.setState({ cards: nexState }) 
 
    } 
 

 
    onSubmit =() => { console.log(this.state.cards) }; 
 

 
    render() { 
 
    const { cards } = this.state; 
 
    return (
 
     <div> 
 
     { 
 
      cards.length < 1 ? "Loading..." : 
 
      <div> 
 
       {cards.map((card, idx) => (
 
       <ul> 
 
        {card.cardName} 
 
        { 
 
        card.options.map((lo, idx) => { 
 
         return <input 
 
         key={idx} 
 
         type="radio" 
 
         name={card.cardName} 
 
         value={lo.radioName} 
 
         checked={!!lo.selected} 
 
         onChange={this.onInputChange} 
 
         /> 
 

 
        }) 
 
        } 
 
       </ul> 
 
      )) 
 
       } 
 
       < button onClick={this.onSubmit}>Print Cards</button> 
 
      </div> 
 
     } 
 

 
     </div> 
 
    ); 
 
    } 
 
} 
 

 
ReactDOM.render(<CardsList />, document.getElementById('root'));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script> 
 
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script> 
 
<div id="root"></div>

संबंधित मुद्दे