0

I want to update question name on onChange event. But problem is every question changes if I change only one ques.How to fix it ?

class QuestionCreate extends React.Component {
    constructor(props){
        super(props);
        this.state = {
            datas: [],
            default_question: {
                isNew: true,
                question: {
                    name: 'Click to write the question text',
                    answer_options: [
                        {name: 'click to write choice 1', 'choice': true},
                        {name: 'click to write choice 1', 'choice': true},
                        {name: 'click to write choice 1', 'choice': true},
                    ]
                }
            }
        }

    }


    onChangeQuestion(qustions, index, event){
        let all_data = this.state.datas;
        let currentQuestion = all_data[index].question
        all_data[index]['question']['name'] = event.target.value;
        console.log(all_data[index]['question']['name'])
        this.setState({datas: all_data})

    }

    displayRow(){
    let rowData = this.state.datas.map( (data, index) =>{
        console.log("this is data:", data, index);
        return(
            <div className="well" key={ index }>
                <h3>Q. <input type="text" onChange={ this.onChangeQuestion.bind(this, data, index) } value={ data.question.name } /></h3>
                    <ul>
                        <li>option</li>
                    </ul>
            </div>
        )
    })

    return rowData;
}

enter image description here

Shaon shaonty
  • 1,367
  • 1
  • 11
  • 22

2 Answers2

2

You are mutating your state directly.

let all_data = this.state.datas;
let currentQuestion = all_data[index].question
all_data[index]['question']['name'] = event.target.value;

Use:

let all_data = JSON.parse(JSON.stringify(this.state.datas));
let currentQuestion = all_data[index].question;
all_data[index]['question']['name'] = event.target.value;
this.setState({datas: all_data});

These questions may also be helpful.

anand
  • 565
  • 2
  • 9
  • You are changing `this.state` by using the above statements. This is not good. You can read https://reactjs.org/tutorial/tutorial.html#why-immutability-is-important to better understand the issue. – anand Oct 24 '17 at 06:00
  • Do ask if you still have any doubts – anand Oct 24 '17 at 06:01
  • onChangeQuestion(qustions, index, event){ let all_data = this.state.datas; let currentQuestion = all_data[index].question let newQues = Object.assign({}, currentQuestion, {name:event.target.value}) this.setState({ datas: all_data }) } – Shaon shaonty Oct 24 '17 at 06:11
  • is there need this line ? this.setState({ datas: all_data }) – Shaon shaonty Oct 24 '17 at 06:12
  • in the line `let all_data = this.state.datas;`, you are assigning a reference to `this.state.datas`. So when you change `all_data`, you change `this.state`. In order to avoid that, you can do `let all_data = JSON.parse(JSON.stringify(this.state.datas));` to create a copy of `this.state.datas`. – anand Oct 24 '17 at 06:25
  • this is not working. Please modify and give me exact code of `onChangeQuestion` method – Shaon shaonty Oct 24 '17 at 06:27
  • Yes you need the this.setState(). State should be changed only using setState, so that your components are updated correctly based on the new state. – anand Oct 24 '17 at 06:28
  • let all_data = JSON.parse(JSON.stringify(this.state.datas)); let currentQuestion = all_data[index].question all_data[index]['question']['name'] = event.target.value; this.setState({datas: all_data}); – anand Oct 24 '17 at 06:32
  • yes now working but why it needs to convert JSON to string? – Shaon shaonty Oct 24 '17 at 06:38
  • It is a little hack to create a copy of an object, without mutating the original object. First convert to string using JSON.stringify. Then convert to object using JSON.parse – anand Oct 24 '17 at 06:42
0

it is working after editing onChangeQuestion function.

onChangeQuestion(qustions, index, event){
    let all_data = JSON.parse(JSON.stringify(this.state.datas)); 
    let currentQuestion = all_data[index].question 
    all_data[index]['question']['name'] = event.target.value; 
    this.setState({datas: all_data});
}
Shaon shaonty
  • 1,367
  • 1
  • 11
  • 22