Home > Mobile >  How to use map function inside a map function REACT wordpress
How to use map function inside a map function REACT wordpress

Time:10-31

i'm creating a wordpress plugin with React - haven't really ever used React before this, so I'm probably misunderstanding something crucial but this is what I'm trying to achieve: You have a button that creates a question for a quiz and then to every button you can add multiple solutions:

DOMquestions = questions.map((question) =>

    <div>
        <div>
            {question.qIdTitle}
        </div>
        <div>
            Type: {question.qTypeTitle}
        </div>
        <div>
            Question title
            <input type={"text"} onChange={question.title = handleTextInputChange}></input>
        </div>
        <div>
            Question description
            <input type={"text"} onChange={question.desc = handleTextInputChange}></input>
        </div>
        <button onClick={() => question.addS(question)}>Add a solution</button>
        <div>
        {
                question.solutions.map((solution) =>
                    {
                        return <div>Solution data and fields appear here</div>
                    }

                )
        }
        </div>
    </div>
);

console.log(DOMquestions);
ReactDOM.render(<div class='w-100'>{DOMquestions}</div>, qc);

The idea is that every Function object has an array full of solution objects inside of it

the addS function pushes a new solution object to the array - so I already have my array The question is how should I go about rendering it on screen Thanks in advance

CodePudding user response:

1- Put the "questions" array in a state.

2- Make a function "updateQuestions" to update the questions array in state

3- Add array index here "DOMquestions = questions.map((question, index)"

4- Send the index of the question object to this function on onClick. "onClick={() => updateQuestions(index)}"

5- now in updateQuestions grab the question object from "questions" array through this index like

questionsArray = {...questions} const question = questionsArray[index]

and add attach the question object to function .adds questionsArray[index].addS(question)

6- Now update the questions state with this new questionArray setQuestions([...questionsArray])

CodePudding user response:

There are multiple mistakes you have made, let's go over them one by one:

  1. From React 18, the render method has been deprecated in favor of createRoot method, and this is how you can implement it:
const DOMquestions = () => <div>...</div>; 
const root = ReactDOM.createRoot(qc);
root.render(
  <DOMquestions />
);

  1. It's better to make your main DOMquestions a functional component, in order to use any of the react functionalists like state, callbacks etc
const DOMquestions = () => {
 return (
  // ...
 )
}
  1. When mapping an array in react you must use key property, this helps react track which items have changed.
questions.map((question) => (
 <div key={question.qIdTitle}>
  {/* ... */}
 </div>
)
  1. Your input change events is written incorrectly, and I'm not sure what you were trying to achieve, but if I will rewrite it I would use useCallback for the input change and it would look like this. Also <input /> is self-closing tag, you don't have to use </input>
const handleTitleInputChange = React.useCallback(event => {
  question.title = event.target.value;
});

return (
  <input value={question.title} onChange={handleTitleInputChange} />
)

Finally, let's bring those all together in one place:

const DOMquestions = () => {
  const handleTitleInputChange = React.useCallback((event, question) => {
    question.title = event.target.value;
  });

  const handleDescInputChange = React.useCallback((event, question) => {
    question.desc = event.target.value;
  });

  return (
    questions.map((question) =>
      <div key={question.qIdTitle}>
        <div>
          {question.qIdTitle}
        </div>
        <div>
          Type: {question.qTypeTitle}
        </div>
        <div>
          Question title
          <input value={question.title} onChange={event => handleTitleInputChange(event, question)} />
        </div>
        <div>
          Question description
          <input value={question.desc} onChange={event => handleDescInputChange(event, question)} />
        </div>
        <button onClick={() => question.addS(question)}>Add a solution</button>
        <div>
          {question.solutions.map((solution) => (
            <div key={solution.id}>Solution data and fields appear here</div>
          ))}
        </div>
      </div>
    )
  )
}

const root = ReactDOM.createRoot(qc);
root.render(
  <DOMquestions />
);
  • Related