使用已绑定的方法来对此未定义进行反应

时间:2019-03-18 18:05:13

标签: javascript reactjs

我有一个react应用程序,我正在尝试使用javascript文件中的数据来构建Navbar组件。

我的NavbarData.js文件如下所示:

const NavbarData = [
    {
        id: 1, 
        text: "Typography"
    },
    {
        id: 2,
        text: "Buttons"
    },
    {
        id: 3,
        text: "icons"
    }
]

export default NavbarData

我正在使用.map()遍历此数据并在App.js文件中创建NavbarItem组件。

// Build navmenu items
const navbarItems = this.state.navbarData.map(function(item){
  return <NavbarItem key={item.id} text={item.text} id={item.id}></NavbarItem>
});

这是我的NavbarItem.js文件

从'react'导入React,{组件};

class NavbarItem extends Component{
    render(){
        return(
            <>
                <li key={this.props.id} id={this.props.id}>{this.props.text}</li>
            </>
        )
    }
}

export default NavbarItem

所有这些使我看起来像这样。哪个很棒。

Image1

但是我想为每个按钮添加一个监听器。由于这是一个单页应用程序,因此我想呈现一个版式,按钮或图标组件。为此,我需要一个函数来更新父组件的状态,在本例中,该组件只是App.js

因此我将以下函数放入App.js

  //This function changes the state so that different components can render
  navClick(id) {
    console.log('changed', id);
  }

我确保将其绑定到App.js的构造函数中

this.navClick = this.navClick.bind(this);

我的整个App.js文件现在看起来像这样

//React stuff
import React, { Component } from 'react';

//Bootstrap stuff
import { Container, Row, Col } from 'reactstrap';

//Layout
import NavbarItem from './layout/NavbarItem'
import NavbarData from './layout/NavbarData'

//Components
import Typography from './components/Typography/Typography'
import Buttons from './components/Buttons/Buttons'

//Styles
import './App.css';
import 'bootstrap/dist/css/bootstrap.min.css';

class App extends Component {
  constructor(){
    super();

    // State determines what component is active and loads navbar data
    this.state = {
      navbarData: NavbarData,
      typography: true,
      buttons: false,
      icons: false
    }

    this.navClick = this.navClick.bind(this);
  }
  //This function changes the state so that different components can render
  navClick(id) {
    console.log('changed', id);
  }

  render() {

    // Build navmenu items
    const navbarItems = this.state.navbarData.map(function(item){
      return <NavbarItem key={item.id} text={item.text} id={item.id}></NavbarItem>
    });


    // Determine what component to display in main area using state
    let elementToDisplay;
    if(this.state.typography){
      elementToDisplay = <Typography></Typography>
    }
    else if(this.state.buttons){
      elementToDisplay = <Buttons></Buttons>
    }

    ////////////////////////////////////////////////////


    return (
      <Container fluid={true}>
        <Row>
          <Col>Header</Col>
        </Row>
        <Row>
          <Col xs="12" sm="12" md="1" lg="1" xl="1">
            <ul>
              {navbarItems}
            </ul>
          </Col>
          <Col xs="12" sm="12" md="11" lg="11" xl="11">
            {elementToDisplay}
          </Col>
        </Row>
        <Row>
          <Col>Footer</Col>
        </Row>
      </Container>
    );
  }
}

export default App;

当我尝试将navClick函数附加到映射的NavbarItem时,就会出现问题。

// Build navmenu items
const navbarItems = this.state.navbarData.map(function(item){
  return <NavbarItem navigationWhenClicked={this.navClick} key={item.id} text={item.text} id={item.id}></NavbarItem>
});

我收到的错误如下:

  

TypeError:这是未定义的

TypeError

在搜索此问题时,这是热门文章。 React: "this" is undefined inside a component function

但这不是我的问题,因为我确保绑定我的函数。

我真的不知道我在做什么错。任何帮助,将不胜感激。

1 个答案:

答案 0 :(得分:3)

您传递给.map的函数也具有自己的this绑定。最简单的解决方案是传递this as second argument to .map

const navbarItems = this.state.navbarData.map(function(item) {
  ...
}, this);
函数内部的

this将设置为您作为第二个参数传递的任何参数,在本例中为组件实例。

或者,您也可以使用箭头函数代替函数表达式,因为this在箭头函数内部是按词法解析的(即像其他变量一样):

const navbarItems = this.state.navbarData.map(
  item => <NavbarItem navigationWhenClicked={this.navClick} key={item.id} text={item.text} id={item.id} />
});

另请参阅:How to access the correct `this` inside a callback?