简体   繁体   中英

Give className to the matched element in forEach loop with React.js

Guys i have a random word in my example and i am spliting that random word's letters to spans.

Then i check if there is specific letter in that word and use forEach loop to achieve this. This is my function;

 getLetter:function(e){
   var val = e.currentTarget.textContent;
    this.state.letters.forEach(function(letter) {
     if (letter === val) {
     alert("There is 'r' letter in the word.")
     e.target.className = 'clicked';
     letter.className='foundedLetter';
    }
});

I can give class e.target but can't give class the matched letter in forEach loop.

How can i make it?

Thanks in advance.

JSFIDDLE

I changed your for-loop definition into a for of loop, to make it more clear for the eye.

    getLetter(e)
    {
        var val = e.currentTarget.textContent;

        for (let letter of this.state.letters) {
            if (letter === val) 
            {
                e.target.className = 'clicked';
                letter.className = 'foundedLetter'
            }
        }
    }

This piece of code should work, unless if the letter variable you wanna give a className to is NOT a string character.

Make sure you rendered the spans as well. you could also look at this.refs and at a reference at your span. with this you can get the DOMElement and set a className to it. I will show you how to use refs to get DOMelements:

 var MyCom = React.createClass({
  getInitialState: function() {
    return {
      random: 'lorem',
      letters:[],
      letter: ''
    }
  },
  splitLetter:function(){
   var s = this.state.random;
   for (var i = 0; i < s.length; i++) {
    this.state.letters.push(s.charAt(i));
   }
   this.setState({
   letters:this.state.letters
   })
  },
  getLetter:function(e){
   var val = e.currentTarget.textContent;
   var _this = this;
    this.state.letters.forEach(function(letter) {
     if (letter === val) {
     alert("There is 'r' letter in the word.")
     console.log(letter, val);
     e.target.className = 'clicked';
     _this.setState({letter: letter})
    }
});
  },
  render: function() {
    return (
      <div>
      <p>The word is: <strong>{this.state.random}</strong></p>
      <p>Click the button first then click the r letter below</p>
        <button onClick={this.splitLetter}>Split letter</button>
        <p>Click on: <strong><span onClick={this.getLetter}>r</span></strong></p>
      {this.state.letters.map(function(item){  
  return (
       <div>
         <span className={item == this.state.letter ? 'foundedLetter' : ''}>{item}</span>  
      </div>
       )
    },this) /*added this to map function  */
    }
    </div>
    )
  }
});

ReactDOM.render(
  <MyCom/>,
  document.getElementById("app")
)

for example: console.log(this.state.letters)

< span > H < /span > --> this you can give className

H --> this you cant give className

If I understand correctly, when the letter to match is 'r' , you want the r in 'lorem' (spelled downwards with line-breaks between each letter) to have a special className. To do that you should selectively set a className in the render method using curly braces and JS-code:

{this.state.letters.map(function(item) {
    return (
        <div className={item === 'r' ? 'selected-letter' : ''}>
            {item}
        </div>
    )
})}

or the same thing using an arrow function.

{this.state.letters.map((item) =>
    <div className={item === 'r' ? 'selected-letter' : ''}>
        {item}
    </div>
)}

Here it is in a fiddle .

Of course, if you want to let the user select letter to match against, then it should be in the component state: fiddle .

{this.state.letters.map((item) =>
    <div className={item === this.state.letterToMatch ? 'selected-letter' : ''}>
        {item}
    </div>
)}

Edit

Fiddle where you can select which letter to highlight as well.

onLetterSelected: function(e) {
    this.setState({
        letterToMatch: e.currentTarget.textContent
    });
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM