Reputation: 17
I have array useState hook which consists of items with className. I want to update className of a single item from that hook. How do I update single value of a useState hook.Of course I am going to put condition before updating . here is the code -
display.map( word =>
( Words[leftPointer] === word.props.children ?
{...display, word:(<span key={uuid()} className="singleWord greenword">
{Words[leftPointer]}</span>)} :
display )
)
setDisplay(display)
here display contains array of span. what I want is go change the className based on the condition example- after updating the item className = "singleWord greenword" should be className="singleWord" of that item.
Upvotes: 0
Views: 170
Reputation: 527
I would recommend against setting className
in the state's domain as that is part of the UI's domain. Instead data changes can be used to signal responses in the UI rendering. This is what it means for a program to be data-driven.
Here is a minimal verifiable example. Run the program below and change some quantities to see the display
state update. The className
is automatically changed based on conditions applied to the application state.
function App() {
const [display, setDisplay] = React.useState([
{item: "walnut", quantity: 0 },
{item: "peanut", quantity: 3 },
{item: "donut", quantity: 6 }
])
function update(index) { return event =>
setDisplay([
...display.slice(0, index),
{ ...display[index], quantity: Number(event.target.value) },
...display.slice(index + 1)
])
}
return <div>
{display.map((d, index) =>
<div key={index}>
{d.item}:
<input
className={d.quantity > 0 ? "instock" : "outofstock" }
value={d.quantity}
onChange={update(index)}
/>
</div>
)}
<div>{display.every(d => d.quantity > 0) ? "✅" : "❌"}</div>
<pre>{JSON.stringify(display, null, 2)}</pre>
</div>
}
ReactDOM.render(<App/>, document.querySelector("#app"))
input { outline: 0 }
.instock { border-color: limegreen; }
.outofstock { border-color: red; }
pre { padding: 0.5rem; background-color: #ffc; }
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.14.0/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.14.0/umd/react-dom.production.min.js"></script>
<div id="app"></div>
Upvotes: 1
Reputation: 341
Map function will return a new array so you just have to store the array in a new variable and set the state with that new variable
const newDisplay = display.map( (word) =>{
if(Words[leftPointer] === word.props.children){
return {word:(<span key={uuid()} className="singleWord greenword">
{Words[leftPointer]}</span>)}
}else{
return word
}
})
setDisplay(newDisplay)
Upvotes: 1
Reputation: 11
could you just use a state variable that holds the text for className
and update that state variable on the useState hook to whatever you want?
Upvotes: 0