Search code examples
javascriptreactjseval

Is this a proper usecase for eval() in Javascript?


I've gone through https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/eval

I am curious if there is a better way to pass this name of the currently clicked panel name to the handlePanelClick(). The line let currentPanel = eval(this.${name}Panel); is what I am concerned about.

I need to have name be evaluated and then set as part of the currentPanel. If I remove the eval() to just 'this.${name}Panel', then currentPanel is not a DOM Element.

Is this a proper use case for using eval()?

        export default class Profiles extends Component {

      constructor(props) {
        super(props);

        this.ul, this.hunterPanel, this.fieldPanel, ...
         // other declarations...
        this.handlePanelClick = this.handlePanelClick.bind(this);

       }

      handlePanelClick(event, name) {
            event.preventDefault();
            const currentScrollPosition = this.ul.scrollLeft;

            let currentPanel = eval(`this.${name}Panel`); //  <-- is this good practice or is there a better way? Removing eval() means `this` is a string and not a reference to the DOM Element that was clicked.
        // move the unordered list to the left into the viewport
            TweenMax.to(this.ul, 0.75, { scrollTo: { x: currentPanel.getBoundingClientRect().left + currentScrollPosition } });    
          }

      render() {
        return (
            <section className="video-slider">
            <ul ref={ul => this.ul = ul}>
              <li ref={ hunterPanel => this.hunterPanel = hunterPanel }>
                /* html elements */
              </li>
              <li ref={ fieldPanel => this.fieldPanel = fieldPanel }>
                /* html elements */
              </li>
             </ul>
    <ul>
          <li><a onClick={() => this.handlePanelClick(event, "hunter")}><span>Hunter</span></a></li>
          <li><a onClick={() => this.handlePanelClick(event, "field")}><span>Field</span></a></li>
</ul>
</section>
    );
  }

Solution

  • You can use the Bracket notation [] to dynamically target a property in an object with a string:

    this[`${name}Panel`]
    

    By the way, eval is evil. Try not to use it, beside the security risk the browsers are dumping some optimizations when using eval .