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
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 typeReact.JSX.Element
so does not have attributes such astextContent
.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
is how you create that state for the paragraph text, you now have one stateful variable.
text
is the value, andsetText
is the setter that lets you update the value. You can name these whatever you want.So the rendering part must be
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.
And it should work as expected.
I don’t know why your solution with
useState
didn’t work, but it’s actually an excellent case for usinguseState
, even more,useState
was created specifically for situations like yours.Here is the solution that uses
useCase
and it works: