我有一个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
所有这些使我看起来像这样。哪个很棒。
但是我想为每个按钮添加一个监听器。由于这是一个单页应用程序,因此我想呈现一个版式,按钮或图标组件。为此,我需要一个函数来更新父组件的状态,在本例中,该组件只是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:这是未定义的
在搜索此问题时,这是热门文章。 React: "this" is undefined inside a component function
但这不是我的问题,因为我确保绑定我的函数。
我真的不知道我在做什么错。任何帮助,将不胜感激。
答案 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} />
});