这个问题在这里已有答案:
我有一个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,{Component};
class NavbarItem extends Component{
render(){
return(
<>
<li key={this.props.id} id={this.props.id}>{this.props.text}</li>
</>
)
}
}
export default NavbarItem
所有这些都给了我一些看起来像这样的东西。哪个好。
但我想为每一个添加一个点击监听器。由于这是一个单页面应用程序,我想渲染一个排版,按钮或图标组件。为此,我需要一个更新父组件状态的函数,在我的例子中只是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:这是未定义的
在Google上搜索此问题时,这是最重要的帖子。 qazxsw poi
但这不是我的问题,因为我确保绑定我的功能。
我真的不知道我在这里做错了什么。任何帮助,将不胜感激。
你传递给React: "this" is undefined inside a component function的功能也有自己的.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} />
});