我正在尝试编写一个非常简单的反应程序,向用户显示一个按钮,单击时,它会调用API并将结果显示为列表。
我正处于可以按下按钮并进行调试的地步我看到数据被拉动并按照我需要的方式进行操作但它没有显示在屏幕上。这是我到目前为止所做的工作;
import React from "react";
import ReactDOM from "react-dom";
class Button extends React.Component {
constructor(props){
super(props);
this.state = {
users : []
};
}
handleClick() {
fetch("http://localhost:8080/api/user/")
.then(results => {
return results.json();
})
.then(data => {
let users = data.map((user) => {
console.log("user - ", user.name);
return (
<li key={user.id}>{user.name}</li>
);
})
// this.setState({users: users});
return (
<ol>
{users}
</ol>
);
})
.catch(function(error) {
console.log(error);
});
}
render(){
return (
<button onClick={this.handleClick}>Get All Users</button>
);
}
}
ReactDOM.render(<Button />, document.getElementById("root"));
答案 0 :(得分:1)
你不能像那样异步返回jsx。我建议将最终的then
修改为如下内容:
.then(data => this.setState({ data }));
您可以将默认data
设置为空数组,这样您就不必担心映射。
class Button extends React.Component {
state = { data: [] };
}
然后,更改渲染以响应state
render() {
return (
<ul>
{data.map(d => <li>{d}</li>)}
</ul>
);
}
要解释,请参阅以下流程:
onClick
进行加载数据的异步调用render
。答案 1 :(得分:1)
以下是我提出的建议:
import React from "react";
import ReactDOM from "react-dom";
function getData(callback) {
fetch("http://localhost:8080/api/user/")
.then(results => {
return results.json();
})
.then(callback);
}
class Button extends React.Component {
constructor(props) {
super(props);
this.handleClick = this.handleClick.bind(this);
this.state = {
data : null
};
}
handleClick() {
this.props.getData(data => this.setState({ data }));
}
_renderUsers() {
return (
<ol>
{
this.state.data.map(user => <li key={ user.id }>{ user.name }</li>)
}
</ol>
);
}
render() {
return (
<div>
<button onClick={ this.handleClick }>Get All Users</button>
{ this.state.data && this._renderUsers() }
</div>
);
}
}
ReactDOM.render(<Button getData={ getData }/>, document.getElementById("root"));
fetch
应该在React组件之外。 React只是关于渲染数据不能进行ajax调用。在上面的代码中,getData
是作为prop传递的外部函数。data
为空,稍后将填充API中的数据。 setState
会触发重新呈现。handleClick
在没有上下文的情况下运行,因此您可能无法执行this.setState
。这就是为什么在构造函数中我们this.handleClick = this.handleClick.bind(this)
。我们将它绑定在组件的上下文中。答案 2 :(得分:0)
您的handleClick
方法只是一个事件处理程序,这意味着当您单击按钮时它会触发,但它实际上并没有呈现任何内容。因此,在此处返回列表不会做任何事情。
相反,请与用户一起更新您的状态,并将其与按钮分开渲染。例如:
import React from "react";
import ReactDOM from "react-dom";
class Button extends React.Component {
constructor(props){
super(props);
this.state = {
users : []
};
}
handleClick() {
fetch("http://localhost:8080/api/user/")
.then(results => {
return results.json();
})
.then(data => {
let users = data.map((user) => {
console.log("user - ", user.name);
return (
<li key={user.id}>{user.name}</li>
);
})
this.setState({users: users});
})
.catch(function(error) {
console.log(error);
});
}
render(){
return (
<div>
<button onClick={this.handleClick}>Get All Users</button>
{this.state.users.length > 0 &&
<ul>
{this.state.users}
</ul>
}
</div>
);
}
}
ReactDOM.render(<Button />, document.getElementById("root"));
答案 3 :(得分:0)
handleClick()方法不应该返回结果,因为它不对它做任何事情,你应该更新一个状态变量,然后更新渲染逻辑
下面有关如何更新点击的简短示例:
(您可以通过jsbin:http://jsbin.com/vumaqam/edit?html,js,output运行/编辑此示例)
class Button extends React.Component {
constructor(props) {
super(props);
this.state = {users:[]};
}
handleClick(){
console.log("clikc");
this.setState({users:["joe","smith"]});
}
getList(){
// key must be unique, if user name is not unique must use other key
return this.state.users.map((user)=>(<li key={user}>{user}</li>));
}
render() {
return (
<div>
<button onClick={()=>{this.handleClick()}}>Get All Users</button>
<ul>{this.getList()}</ul>
</div>
);
}
}
React.render(
<Button />,
document.getElementById('react_example')
);