React Component OnClick

hello everyone! in 3rd reeact project i should create recipe box, i want to show recipes’ names with while loop, should I to add onClick into my label like this?

while (i < list.length) {
    this.setState({
        html: html += '<div><label class="recipeName"> onClick={}' + list[i].name + '</label></div>'
    })
    i++
}

full code

class Recipes extends React.Component {
    constructor(props) {
        super(props)
        this.state = {
            list: this.props.array,
            html: ''
        }
    }

    componentDidMount() {
        if (this.state.list.length > 0){
            var i = 0
            var list = this.state.list
            var html = this.state.html
            while (i < list.length) {
                this.setState({
                    html: html += '<div><label class="recipeName">' + list[i].name + '</label></div>'
                })
                i++
            }
        }
    }

    render() {
        return(
            <div dangerouslySetInnerHTML={{__html: this.state.html}}> </div>
        )
    }
}
  • The markup is wrong for the click attribute, and you need to explain what you’re trying to do: what do you want to happen on click?
  • Labels are for input elements, they aren’t just an arbitrary tag you use. Use a list, or individual <p> elements.
  • There’s absolutely no need to usedangerouslySetInnerHTML here: the method is an escape hatch for if you want to do something weird. 99.9% of the time you should never need to use it.
  • Try not to call the properties generic names: list is a list of what? You know it’s a list, similarly the prop array, you know it’s an array. Give it a name that describes what it actually is. I assume it’s a list of the names of recipes, but not possible to tell from the code.
  • Don’t initialise the state from the properties, it’s an antipattern: the properties are already there, you don’t need to duplicate them into state.
class Recipes extends React.Component {
  constructor(props) {
    super(props);
    
    this.myClickHandler = this.MyClickHandler.bind(this);
  }

  myClickHandler() {
    console.log('You just clicked a recipe name.')
  }

  render() {
    <ul className="recipe-names">
      { this.props.recipeNames.map((recipeName, i) =>
        <li className="recipe-name" key={ `recipe-name-${i}` } onClick={ this.myClickHandler}>{ recipeName }</li>
      )}
    </ul>
  }
}
1 Like

why dangerouslySetInnerHTML so bad? How can i put different html code in render without dangerouslySetInnerHTML? If html code i need in this.state.html for example and i write

<div>
    {this.state.html}
</div>

this.state.html = 
'<div>
    <p>sometext</p>
</div>'

i see

<div>
    <p>sometext</p>
</div>

instead of sometext on my page

The clue is in the name :wink:

Literally just render the markup. I think I don’t quite understand why you’re trying to avoid using React here: dangerouslySet exists for times when you really need to bypass React, and you’re trying to use it to override what React is designed to do you might as well not use React if you manually render HTML