使用已绑定的方法对此未定义做出react

IT技术 javascript reactjs
2021-05-09 05:52:40

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

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

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

export default NavbarData

我正在使用.map()迭代这些数据并NavbarItem在我的 App.js 文件中创建组件。

// 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 文件

import React, { Component } from 'react';

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

export default NavbarItem

所有这些都给了我看起来像这样的东西。这很棒。

图片1

但我想为每一个添加一个点击监听器。由于这是一个单页应用程序,我想呈现排版、按钮或图标组件。为此,我需要一个函数来更新父组件的状态,在我的情况下它只是 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>
});

我收到的错误如下:

类型错误:这是未定义的

类型错误

在谷歌搜索这个问题时,这是最重要的帖子。 react:“this”在组件函数中未定义

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

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

1个回答

您传递给的函数.map也有自己的this绑定。最简单的解决方案是this 作为第二个参数.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} />
});

另请参阅:如何在回调中访问正确的“this”?