2016-05-08 3 views
1

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

В приведенном ниже примере я представляю некоторый контент, значение которого исходит из серии вложенных функций. Тем не менее, я получаю сообщение об ошибке «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> 
    ) 
    } 
} 

ответ

6

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

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

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

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- Определим переменную:

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.

+1

Большое вам спасибо. Я использовал функцию толстой стрелки, и она отлично работала. Что еще более важно, я понял эту концепцию. – asanas

2

Контекст изменяется внутри функции карты, поэтому «это» указывает на что-то другое. Если вы хотите иметь «правильный», вы можете использовать arrow function, который имеет лексическое «это».

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

Основная проблема заключается в том, что вы передаете функцию data.map, и в этой области «это» не является вашей внешней областью (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); 

Или использовать привязку:

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

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

1

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

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

Смежные вопросы