>我尝试映射一个数组并在数组项目上放置单击事件。我知道它有点不同,因为 JavaScript 处理函数的方式,但我无法让它工作。我收到错误:无法读取未定义的属性"保存存储"。谁能告诉我我做错了什么?提前感谢!这是我的代码:
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>
);
}
}
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的答案(。箭头函数也可以工作的唯一原因是因为"箭头函数没有自己的这个;使用封闭执行上下文的 this 值"(https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/Arrow_functions(。在您的案例中,封闭执行是您的渲染,其中定义了this
。
您需要对代码进行两项更改,如下所述。
-
呈现组件时调用函数。要修复此问题,请将此行更新为以下内容
<p key={i} onClick={() => this.saveInStorage(user)}>
这意味着只有在您单击该项目时才会调用该函数。
-
您还需要在构造函数中绑定
renderUser
或使用箭头函数。this.renderUser = this.renderUser.bind(this);
请参阅此处的工作示例。
您的onClick
事件处理程序是错误的。只需将其更改为:
onClick={() => this.saveInStorage(user)}
不要忘记在构造函数中绑定renderUser
。或者,您可以选择箭头函数方法,因为它们的工作方式与绑定相同:
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>
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 都在一个函数中。
您不会将参数发送到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>
);
}
}