我正在学习React,并且正在尝试做一个小项目。该项目正在显示jsonPlaceholder
的用户列表,并希望使其编辑字段。
我有一个用于加载列表的div,另一个具有可编辑字段的隐藏div,还有一个按钮,当单击列表div时该按钮被隐藏,另一个按钮出现。
当我单击按钮时,出现以下错误:
“ TypeError:无法读取未定义的属性'handleClick'”
有人可以帮忙吗?
import React from 'react';
import './App.css';
class User extends React.Component {
constructor(){
super();
this.state = {
users: [],
displayList: 'block',
displayForm: 'none'
}
this.handleClick = this.handleClick.bind(this);
}
componentDidMount(){
this.getUsers();
}
getUsers(){
fetch('https://jsonplaceholder.typicode.com/users')
.then(response => response.json())
.then(json => this.setState({users: json}));
}
handleClick(){
this.setState({displayList: 'none', displayForm: 'block'})
}
render(){
const list = this.state.displayList;
const form = this.state.displayForm;
return (
<ul>
{this.state.users.map(function(item){
return (
<div key={item.id}>
<br></br>
<div style={{display: list}}>
<h2>{item.name} </h2>
<p>Email: {item.email} </p>
<p>Address: </p>
<ul>
<li>Street: {item.address.street} </li>
<li>Suite: {item.address.suite} </li>
<li>City: {item.address.city} </li>
<li>ZipCode: {item.address.zipcode} </li>
</ul>
<p>Phone: {item.phone} </ p>
</div>
<div style={{display: form}} >
<div>
<h2>{item.name} </h2>
<p>Email: <input value = {item.email} className="form-control" onChange=""/> </p>
<p>Address: </p>
<ul>
<li>Street: <input value = {item.address.street} className="form-control" /> </li>
<li>Suite: <input value = {item.address.suite} className="form-control" /> </li>
<li>City: <input value = {item.address.city} className="form-control" /> </li>
<li>ZipCode: <input value = {item.address.zipcode} className="form-control" /> </li>
</ul>
<p>Phone: <input value = {item.phone} className="form-control" /> </p>
</div>
</div>
<button onClick={() => this.handleClick()}> Edit </button>
<hr></hr>
</div>
)
})}
</ul>
);
}
}
export default User;
答案 0 :(得分:2)
这是因为未绑定映射方法this.state.users.map
中的回调。您需要将其变成箭头功能。像这样:
import React from 'react';
import './App.css';
class User extends React.Component {
constructor(){
super();
this.state = {
users: [],
displayList: 'block',
displayForm: 'none'
}
this.handleClick = this.handleClick.bind(this);
}
componentDidMount(){
this.getUsers();
}
getUsers(id){
fetch('https://jsonplaceholder.typicode.com/users')
.then(response => response.json())
.then(json => this.setState({users: json}));
}
handleClick(){
this.setState({displayList: 'none', displayForm: 'block'})
}
render(){
const list = this.state.displayList;
const form = this.state.displayForm;
return (
<ul>
{this.state.users.map((item => {
return (
<div key={item.id}>
<br></br>
<div style={{display: list}}>
<h2>{item.name} </h2>
<p>Email: {item.email} </p>
<p>Address: </p>
<ul>
<li>Street: {item.address.street} </li>
<li>Suite: {item.address.suite} </li>
<li>City: {item.address.city} </li>
<li>ZipCode: {item.address.zipcode} </li>
</ul>
<p>Phone: {item.phone} </ p>
</div>
<div style={{display: form}} >
<div>
<h2>{item.name} </h2>
<p>Email: <input value = {item.email} className="form-control" onChange=""/> </p>
<p>Address: </p>
<ul>
<li>Street: <input value = {item.address.street} className="form-control" /> </li>
<li>Suite: <input value = {item.address.suite} className="form-control" /> </li>
<li>City: <input value = {item.address.city} className="form-control" /> </li>
<li>ZipCode: <input value = {item.address.zipcode} className="form-control" /> </li>
</ul>
<p>Phone: <input value = {item.phone} className="form-control" /> </p>
</div>
</div>
<button onClick={this.handleClick}> Edit </button>
<hr></hr>
</div>
)
}))}
</ul>
);
}
}
export default User;
答案 1 :(得分:0)
问题是this.handleClick
在定义为常规function
的回调中被引用,该回调传递给map
。常规函数的their own values中的this
不是组件。
为了进行retain the value of this调用,您需要将回调函数作为箭头函数传递给地图:
render () {
/* ... */
return (
<ul>
{this.state.users.map((item) => { /* ... */ })}
</ul>
)
}
或者,您可以将this
值作为第二个参数显式传递给map
render () {
/* ... */
return (
<ul>
{this.state.users.map(function(item) { /* ... */ }, this)}
</ul>
)
}
答案 2 :(得分:0)
您必须将方法绑定到对象。
要么:
handleClick = () => {
this.setState({displayList: 'none', displayForm: 'block'})
}
或:
<button onClick={this.handleClick.bind(this)}> Edit </button>
否则,它将失去上下文。