skip to Main Content

I am a React noob. This is my practice project reduced down to the essentials.

function App() {
   var myParagraph = <p>Rutabaga</p>;
   function MyClickHandler() {
      myParagraph.textContent = "CARROT"; // ERROR
   }
   var myButton = <button onClick={MyClickHandler}>MY BUTTON</button>
   return <>{myParagraph}{myButton}</>
}

export default App;

My actual practice project is lot bigger than this. What I’ve written here is the minimum to reproduce the problem I’m having. It displays the text and button, but when I click the button I get an error.

I’d like for the line marked // ERROR to replace the inner text contents of the <p> with new text. I imagine there should be a single line of code that will replace the contents with my new text, or maybe I need to supply some placeholder inside the paragraph that can be written into later on.

I’ve tried using setState, but I get the same error complaining that it cannot set that property.

2

Answers


  1. Roughly speaking, one of the main aspects of react is to be declarative, and on top of that it uses a virtual dom, so you shouldn’t really be holding references to elements, or trying to.

    In React what’s returned from JSX (<div>...</div>) is not an HTML element, its of type React.JSX.Element so does not have attributes such as textContent.

    You should be using state, in React state is a way to hold variables that can change over time. So the value of the text in your paragraph is the state in this situation. So

    const [text, setText]=useState("Rutabaga");
    

    is how you create that state for the paragraph text, you now have one stateful variable. text is the value, and setText is the setter that lets you update the value. You can name these whatever you want.

    So the rendering part must be

      return (
        <>
          <button onClick={MyClickHandler}>MY BUTTON</button>
          <p>{text}</p>{" "}
        </>
      );
    

    where you pass the state as part of the JSX to render.

    And then, the handler should set the state, rather than trying to set the element value.

    
    function MyClickHandler() {
      setText("CARROT")
    }
    
    

    And it should work as expected.

    Login or Signup to reply.
  2. I don’t know why your solution with useState didn’t work, but it’s actually an excellent case for using useState, even more, useState was created specifically for situations like yours.

    Here is the solution that uses useCase and it works:

    import React, { useState } from 'react';
    
    function App() {
      const [text, setText] = useState("Rutabaga");
    
      function MyClickHandler() {
        setText("CARROT");
      }
    
      return (
        <>
          {/* Use the state variable in the paragraph */}
          <p>{text}</p>
          <button onClick={MyClickHandler}>MY BUTTON</button>
        </>
      );
    }
    
    export default App;
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search