0

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.

Rk Shawon
  • 17
  • 4
  • So `display` is an array of "span" and you want to change the `className` of only one "span" ? What is the condition to identify that specific "span" ? – Bao Huynh Lam Feb 24 '22 at 14:28
  • I am comparing my input word with the word inside span(I did it) the problem is I don't know how to update single item of a state my code does not do anything – Rk Shawon Feb 24 '22 at 15:13

3 Answers3

1

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)
Shambhu Sahu
  • 342
  • 2
  • 4
1

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>
よつば
  • 467
  • 1
  • 8
0

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?

  • it would be helpful if you kindly give a demo. – Rk Shawon Feb 24 '22 at 15:25
  • Your answer could be improved with additional supporting information. Please [edit] to add further details, such as citations or documentation, so that others can confirm that your answer is correct. You can find more information on how to write good answers [in the help center](/help/how-to-answer). – Community Feb 24 '22 at 21:36