skip to Main Content

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

2

Answers


  1. 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])

    Login or Signup to reply.
  2. 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 functionalities 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 />
    );
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search