Вложенные функции в JS

Я пытаюсь понять некоторые концепции в responsejs, но я не могу понять вложение функций. Я создал приведенный ниже пример для расследования моей проблемы.

В приведенном ниже примере я рендеринг некоторого контента, значение которого исходит из ряда вложенных функций. Тем не менее я получаю сообщение об ошибке "Uncaught TypeError: Невозможно прочитать свойство 'renderInnerContent' неопределенного". Не могли бы вы помочь мне понять, что происходит и как решить эту проблему? Мой основной мотив - понять, как абстрагировать вещи в разные функции.

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>
    )
  }
}

4 ответа

Решение

this не определено в контексте этой функции:

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

Потому что это новая функция. У вас есть разные варианты для прохождения this к этой функции:

1- Жирная стрелка

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

2- Определить переменную:

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- Использование 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: Не уверен, что что-то из этого не работает в React.

Основная проблема заключается в том, что вы передаете функцию в data.map, и в этой области "this" не является вашей внешней областью (ChartsArea), но по умолчанию она ссылается на глобальный объект (окно), потому что это анонимная функция.

Таким образом, чтобы это сработало, вы можете сделать это:

var that = this; 

const displaydata = data.map(function(point){
      return (
        <div key={point}>{that.renderInnerContent()}</div>
      )
    });

Или передайте свой контекст во втором аргументе.map:

const displaydata = data.map(function(point){
      return (
        <div key={point}>{that.renderInnerContent()}</div>
      )
    }, this);

Или используйте bind:

const displaydata = data.map(function(point){
      return (
        <div key={point}>{that.renderInnerContent()}</div>
      )
    }.bind(this));

Или используйте функции стрелок, как кто-то еще указал.

Контекст изменяется внутри функции карты, поэтому "this" указывает на что-то еще. Если вы хотите иметь "правильное" это, вы можете использовать функцию стрелки, которая имеет лексическое "это".

const displaydata = data.map(point => {
  return (
    <div key={point}>{this.renderInnerContent()}</div>
  )
});

Самый короткий, который я использую, это:
<div>{this.renderContent.bind(this).call()}</div>,

Иногда они становятся немного уродливыми с моей точки зрения, но это самая короткая.

Другие вопросы по тегам