0

Here is a demo.

I want to access this inside an array. Specifically,

this.props.categoryOpen.toString()

throws an error when used as follows.

https://codesandbox.io/s/23l3p906z
import React, { Component } from "react";

class Child extends Component {
  render() {
    return (
      <div>
        {this.props.categoryOpen.toString()}
        {this.rows.map(row => (
          <div>
            {row.cells.map(cell => (
              <div key={cell.label}>
                {cell.label}: {cell.data}
              </div>
            ))}
          </div>
        ))}
      </div>
    );
  }

  rows = [
    {
      cells: [
        {
          label: "Cell A",
          data: {this.props.categoryOpen.toString()}, // breaks
          //data: "Foo" // works
        },
        {
          label: "Cell B",
          data: "Bar"
        }
      ]
    }
  ];
}

export default Child;

An arrow function also throws an error.

rows = () => [...

How can I access this?

breaking code illustration

2
  • The problem is not ` this`, the problem is that you have a syntax error. The brackets indicate that you're trying to create an object but there is no key. What is the shape you want for your data? Commented Sep 4, 2018 at 10:55
  • Why don't you create a global variable which is declared in the scope of the module and assign it 'this' before going into your map function, then use the global? Commented Sep 4, 2018 at 14:44

5 Answers 5

3

Remove {} around data. It should work

Updated codesandbox: https://codesandbox.io/s/y0oo2v1xvv

Sign up to request clarification or add additional context in comments.

Comments

2

Don't statically define your rows like that, or in the constructor, because they won't update when the input props change. In order to have the component re-render automatically when the props change you need to re-generate the rows in the render function.

So just make a method in your component called getRows (or something) and call that from render. That'll have the side effect of making this properly and normally accessible too.

class Child extends Component {
  getRows() {
    return [
      {
        cells: [
          {
            label: "Cell A",
            data: this.props.categoryOpen.toString(),
          },
          {
            label: "Cell B",
            data: "Bar"
          }
        ]
      }
    ];
  }

  render() {
    const rows = this.getRows()
    return (
      <div>
        {this.props.categoryOpen.toString()}
        {rows.map(row => (
          <div>
            {row.cells.map(cell => (
              <div key={cell.label}>
                {cell.label}: {cell.data}
              </div>
            ))}
          </div>
        ))}
      </div>
    );
  }


}

export default Child;

Of course you could just generate rows inline in the render method too, but breaking it out into its own method can help with readability.

Comments

1

Just remove the curly braces

{
    label: "Cell A",
    data: this.props.categoryOpen.toString(), // remove curly braces
    //data: "Foo" // works
}

Comments

1

As pointed by other comments you have a syntax error in the data field definition. Also I did not know this but apparently you can make reference to the lexical context (which is the current component instance here) in class field definition. Worth noting they are not part of the language yet and I would advise to use the constructor for this, which is equivalent as per the Babel transform.

rows is a field which is defined at construction time, if you want to refer to the current instance you need to use the constructor

class Child extends Component {
  constructor () {
    this.rows = [
      {
        cells: [
          {
            label: "Cell A",
            data: this.props.categoryOpen.toString(), // breaks
            //data: "Foo" // works
          },
          {
            label: "Cell B",
            data: "Bar"
          }
        ]
      }
    ];
  }
  render() {
    return (
      <div>
        {this.props.categoryOpen.toString()}
        {this.rows.map(row => (
          <div>
            {row.cells.map(cell => (
              <div key={cell.label}>
                {cell.label}: {cell.data}
              </div>
            ))}
          </div>
        ))}
      </div>
    );
  }

}

Comments

0

wrap variable with ticks like this.

data: `${this.props.categoryOpen.toString()}`,

this should be fine

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.