2

I have a few text inputs on my form that are not working correctly. I cannot see what is being typed and the fields unfocus after just one character. Here's the pieces of my code where it's at:

      constructor(props) {
        super(props);
        this.state = {
          key: uuid(),
          title: "",
          author: "",
          questions: [],
          answers: []
        };

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

      componentDidMount() {
        // componentDidMount() is a React lifecycle method
        this.addQuestion();
      }

      handleChange(event) {
        const target = event.target;
        const value = target.type === "checkbox" ? target.checked : target.value;
        const name = target.name;

        this.setState({
          [name]: value
        });
      }

//yada yada

render() {
//yada yada
    {this.state.questions.map((question, index) => {
                    return (
                      <li>
                      <div key={uuid()}>
                        Question
                        {question}<br />
                        <button onClick={ () => this.removeItem(index) }>
                      Remove Question
                    </button>
                        Answer Choices<br />
                        {Array.from({ length: 4 }, () => (
                          <div>
                            <input type="checkbox" key={uuid()}/>
                            <input type="text" key={uuid()} onChange={this.handleChange} />
                          </div>
                        ))}
                      </div>
                      </li>
                    );
                  })}
//yada yada
}
export default App;

I am very new to this so any tips directly related to this issue or not would be super helpful. Thanks!

1 Answer 1

1

You are giving your elements unique keys each render with uuid(), which will destroy the element and mount a new one. Remove the key={uuid()} and it will work.

{this.state.questions.map((question, index) => {
  return (
    <li key={index}>
      <div>
        Question
        {question}
        <br />
        <button onClick={() => this.removeItem(index)}>
          Remove Question
        </button>
        Answer Choices<br />
        {Array.from({ length: 4 }, (_element, index) => (
          <div key={index}>
            <input type="checkbox" />
            <input type="text" onChange={this.handleChange} />
          </div>
        ))}
      </div>
    </li>
  );
})}
Sign up to request clarification or add additional context in comments.

7 Comments

Thanks for the advice, I tried it out but it didn't seem to work
@dorkycam I updated the answer. Why are you even using uuid() as key? Please read the section on List and Keys in the documentation.
This worked, thanks. I was using uuid() as a key because I have four answer inputs per question, and the number of questions varies upon the user. The user has the ability to add as many questions as they would like (i'll probably add a limit to that later) so I thought that in order to keep track of which set of questions goes with which question I gave them all uuid(). I didn't come up with this myself, it was a tip from someone else. I also found other articles online saying that using index as a key is a bad idea.
@dorkycam I can't say for certain, but I think you misunderstood that tip. If you give a uuid to each object in your data, that would make sense. That way you could reuse that same uuid every render, but setting key as a new uuid() each render is a very bad idea.
Lol ok, how do you suggest I give each object a uuid() then?
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.