我尝试映射数组并将click事件放在数组项上。我知道它有点不同,因为JavaScript如何处理函数,但我不能使它工作。我收到错误:无法读取未定义的属性'saveInStorage'。谁能告诉我我做错了什么?提前致谢!这是我的代码:
import React from "react";
const data = require('../data.json');
export default class Gebruikers extends React.Component {
constructor() {
super();
this.state = {
users: data.users
};
this.saveInStorage = this.saveInStorage.bind(this)
}
saveInStorage(e){
console.log("test");
}
renderUser(user, i) {
return(
<p key={i} onClick={this.saveInStorage(user)}>f</p>
);
}
render() {
return (
<div>
{
this.state.users.map(this.renderUser)
}
</div>
);
}
}
答案 0 :(得分:2)
this
中未定义 renderUser()
您需要在构造函数中绑定this
renderUser()
。
此外,每次渲染组件时都会调用saveInStorage()
,而不仅仅是onClick,因此您需要在renderUser
中使用箭头函数
import React from "react";
const data = require('../data.json');
export default class Gebruikers extends React.Component {
constructor() {
super();
this.state = {
users: data.users
};
this.saveInStorage = this.saveInStorage.bind(this);
this.renderUser = this.renderUser.bind(this);
}
saveInStorage(e){
console.log("test");
}
renderUser(user, i) {
return(
<p key={i} onClick={() => this.saveInStorage(user)}>
);
}
render() {
return (
<div>
{
this.state.users.map(this.renderUser)
}
</div>
);
}
}
除了绑定,您还可以使用箭头功能(根据mersocarlin的回答)。箭头函数也可以工作的唯一原因是“箭头函数没有自己的这个;使用封闭执行上下文的这个值”(https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/Arrow_functions)。在您的情况下,封闭执行是您的渲染,其中定义了this
。
答案 1 :(得分:1)
您的onClick
事件处理程序错误。
只需将其更改为:
onClick={() => this.saveInStorage(user)}
不要忘记在构造函数中绑定renderUser
。
或者,您可以选择箭头函数方法,因为它们的工作方式与bind相同:
class Gebruikers extends React.Component {
constructor(props) {
super(props)
this.state = {
users: [{ id: 1, name: 'user1' }, { id: 2, name: 'user2' }],
}
}
saveInStorage = (e) => {
alert("test")
}
renderUser = (user, i) => {
return(
<p key={i} onClick={() => this.saveInStorage(user)}>
{user.name}
</p>
)
}
render() {
return (
<div>{this.state.users.map(this.renderUser)}</div>
);
}
}
ReactDOM.render(
<Gebruikers />,
document.getElementById('root')
)
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>
<div id="root"></div>
答案 2 :(得分:1)
您需要对代码进行两处更改,如下所示。
在呈现组件时调用该函数。要修复此更新,请将此行更新为以下
<p key={i} onClick={() => this.saveInStorage(user)}>
这意味着只有在单击项目时才会调用该函数。
您还需要在构造函数中绑定renderUser
,否则请使用箭头函数。
this.renderUser = this.renderUser.bind(this);
参见工作示例here。
答案 3 :(得分:1)
Paul Fitzgeralds的回答是正确的,尽管我想提出一种不同的处理方法,但没有所有约束性问题。
import React from "react";
const data = require('../data.json');
export default class Gebruikers extends React.Component {
constructor() {
super();
this.state = {
users: data.users
};
}
saveInStorage = (e) => {
console.log("test");
};
render() {
return (
<div>
{this.state.users.map((user, i) => {
return (<p key={i} onClick={() => this.saveInStorage(user)}>f</p>);
})}
</div>
);
}
}
使用saveInStorage = (e) => {};
,您将saveInStorage函数绑定到类的this
上下文。在调用saveInStorage时,您将始终拥有(至少在这种情况下我猜是这样)期望的this
上下文。
renderUser
函数基本上是多余的。如果返回一行JSX,则可以在渲染函数中轻松完成。我认为它提高了可读性,因为你的所有JSX都在一个函数中。
答案 4 :(得分:0)
您没有将参数发送到this.renderUser
this.state.users.map((user, i) => this.renderUser(user, i))
此外,您的onClick功能应略有改变。这是完整的代码更改:
import React from "react";
const data = require('../data.json');
export default class Gebruikers extends React.Component {
constructor() {
super();
this.state = {
users: data.users
};
this.saveInStorage = this.saveInStorage.bind(this)
}
saveInStorage(e){
console.log("test");
}
renderUser(user, i) {
return(
<p key={i} onClick={() => this.saveInStorage(user)}>f</p>
);
}
render() {
return (
<div>
{
this.state.users.map((user, i) => this.renderUser(user, i))
}
</div>
);
}
}