0

I'm trying to create a dynamic list of views managed in a home component that can be saved and loaded. The save and load functions work fine but I get the following error when calling it in the span's returned from the map function in the Footer.js render method

Uncaught TypeError: Cannot read property 'props' of undefined

How can I access this function call in these elements?

Footer.js

export default class Footer extends React.Component {
constructor(props) {
    super(props);
}

render() {

    return (
        <div className="footer hbox">
            <div className="views hbox">

                <span onClick={ (e) => this.props.getViewNames() }>Get Views</span>
                <span onClick={ (e) => this.props.saveView('test3')}>Save View</span>
                <span onClick={(e) => this.props.loadView('test3')}>Load View</span>

                    {this.props.getViewNames().map(function(viewName){
                      return (
                        <span onClick={(e)=>this.props.loadView(viewName)}>
                        {viewName}
                      </span>
                      );
                    })}

        </div>
    );
 }
}
Ava Shaw
  • 3
  • 1

2 Answers2

0

You forgot to use an arrow function for getViewNames.map(), and thus the lexical scope of this is not kept in your code -- which is interesting, considering you did use the correct approach everywhere else.

So just do:

this.props.getViewNames().map(viewName => {
    ...
});

Also see:

Community
  • 1
  • 1
John Weisz
  • 30,137
  • 13
  • 89
  • 132
0

The reason you cannot access props inside the map function is because this inside your function refers to the context of the map function, and not React Component. You will need to bind your map function to the React Component context by using bind(this) on the map function or arrow functions

Using bind(this)

export default class Footer extends React.Component {
constructor(props) {
    super(props);
}

render() {

    return (
        <div className="footer hbox">
            <div className="views hbox">

                <span onClick={ (e) => this.props.getViewNames() }>Get Views</span>
                <span onClick={ (e) => this.props.saveView('test3')}>Save View</span>
                <span onClick={(e) => this.props.loadView('test3')}>Load View</span>

                    {this.props.getViewNames().map(function(viewName){
                      return (
                        <span onClick={(e)=>this.props.loadView(viewName)}>
                        {viewName}
                      </span>
                      );
                    }.bind(this))}

        </div>
    );
 }
}

using arrow function

export default class Footer extends React.Component {
    constructor(props) {
        super(props);
    }

    render() {

        return (
            <div className="footer hbox">
                <div className="views hbox">

                    <span onClick={ (e) => this.props.getViewNames() }>Get Views</span>
                    <span onClick={ (e) => this.props.saveView('test3')}>Save View</span>
                    <span onClick={(e) => this.props.loadView('test3')}>Load View</span>

                        {this.props.getViewNames().map((viewName) => {
                          return (
                            <span onClick={(e)=>this.props.loadView(viewName)}>
                            {viewName}
                          </span>
                          );
                        })}

            </div>
        );
     }
    }
Shubham Khatri
  • 270,417
  • 55
  • 406
  • 400