asanas asanas - 7 months ago 20
Javascript Question

Nesting Functions in JS

I am trying to understand some concepts in reactjs, but I'm unable to understand nesting of functions. I created the below example for investigating my concern.

In the below example, I'm rendering some content the value of which is coming from a series of nested functions. However, I get the error "Uncaught TypeError: Cannot read property 'renderInnerContent' of undefined". Can you please help me understand what's happening and how to resolve this problem? My primary motive is to understand how to abstract things into different functions.

import React, { Component } from 'react';

export default class MyComponent extends Component {
renderInnerContent() {
return (
<div>Innercontent</div>
)
}

renderContent() {
let data = ["a","b","c"];
const displaydata = data.map(function(point){
return (
<div key={point}>{this.renderInnerContent()}</div>
)
});
return (
<div>{displaydata}</div>
)
}

render() {
return (
<div>{this.renderContent()}</div>
)
}
}

Answer

this is not defined in that function's context:

function(point){
  return (
    <div key={point}>{this.renderInnerContent()}</div>
  )
}

Because it is a new function. You have different options to pass this to that function:

1- Fat arrow function:

renderContent() {
   let data = ["a","b","c"];
   const displaydata = data.map((point) => {
      return (
        <div key={point}>{this.renderInnerContent()}</div>
       )
   });
   return (
      <div>{displaydata}</div>
   )
}

2- Define a variable:

renderContent() {
   let data = ["a","b","c"];
   let _this = this;
   const displaydata = data.map(function(point){
      return (
        <div key={point}>{_this.renderInnerContent()}</div>
       )
   });
   return (
      <div>{displaydata}</div>
   )
}

3- Use bind:

renderContent() {
   let data = ["a","b","c"];
   const displaydata = data.map(function(point){
      return (
        <div key={point}>{this.renderInnerContent()}</div>
       )
   }.bind(this));
   return (
      <div>{displaydata}</div>
   )
}

PS: Not sure any of these is not working in React.