要点:ajax的封装, componentWillReceiveProps(nextProps)--父组件传子组件数据时,子组件通过父组件传过来的的数据 去请求得到新的数据 来展示
src:components+utils+index.css+index.js
utils文件夹:ajax.js
export default function get (url) {
return new Promise(function(resolve, reject) {
// 创建request对象
const xhr = new XMLHttpRequest();
// 添加状态改变的监听
xhr.addEventListener('readystatechange', function() {
if (xhr.readyState === 4 && xhr.status === 200) {
try {
// 解析响应数据
const data = JSON.parse(xhr.responseText);
// 调用成功的回调
resolve(data);
} catch (e) {
// 调用失败的回调
reject(e);
}
}
});
// 添加请求失败的监听
xhr.addEventListener('error', function(error) {
// 调用失败的回调
reject(error);
});
// 打开连接
xhr.open('GET', url);
// 发送请求
xhr.send(null);
});
}
components文件夹:App.js +Search.js +UserList.js
App.js:
import React from 'react';
import Search from './Search';
import UserList from './UserList';
export default class App extends React.Component {
constructor (props) {
super(props);
this.state = {
searchName: ''
};
this.refreshName = this.refreshName.bind(this);
}
refreshName (searchName) {
this.setState({ searchName });
}
render () {
return (
<div className="container">
<section className="jumbotron">
<h3 className="jumbotron-heading">Search Github Users</h3>
<Search refreshName={this.refreshName}/>
</section>
<UserList searchName={this.state.searchName}/>
</div>
);
}
}
Search.js:搜索模块
import React, { Component, PropTypes } from 'react';
class Search extends Component {
constructor (props) {
super(props);
// this.search = this.search.bind(this);
}
search = () => {
var name = this.nameInput.value;
this.props.refreshName(name);
}
render () {
return (
<div>
<input type="text" placeholder="enter the name you search"
ref={(input=>this.nameInput = input)}/>
<button onClick={this.search}>Search</button>
</div>
);
}
}
Search.propTypes = {
refreshName: PropTypes.func.isRequired
};
export default Search;
UserList.js:列表模块
import React, { Component, PropTypes } from 'react';
import ajax from '../utils/ajax';
import axios from 'axios'
class UserList extends React.Component {
constructor (props) {
super(props);
this.state = {
firstView: true,
loading: false,
users: null,
error: null
};
}
componentWillReceiveProps(nextProps) {
let searchName = nextProps.searchName;
console.log('发送ajax请求', searchName);
const url = `https://api.github.com/search/users?q=${searchName}`;
this.setState({ firstView: false, loading: true });
ajax(url).then(
data => {
this.setState({ loading: false, users: data.items })
},
error => {
this.setState({ loading: false, error: error })
}
);
/*axios.get(url)
.then((response) => {
console.log(response)
this.setState({ loading: false, users: response.data.items })
})
.catch((error)=>{
console.log(error)
this.setState({ loading: false, error: error.toString() })
})*/
}
render () {
if (this.state.firstView) {
return <h2>Enter name to search</h2>;
} else if (this.state.loading) {
return <h2>Loading result...</h2>;
} else if (this.state.error) {
return <h2>{this.state.error}</h2>;
} else {
return (
<div className="row">
{
this.state.users.map((user) => (
<div className="card" key={user.html_url}>
<a href={user.html_url} target="_blank">
<img src={user.avatar_url} style={{width: '100px'}}/>
</a>
<p className="card-text">{user.login}</p>
</div>
))
}
</div>
);
}
}
}
UserList.propTypes = {
searchName: PropTypes.string.isRequired
};
export default UserList;
index.css:
.album {
min-height: 50rem; /* Can be removed; just added for demo purposes */
padding-top: 3rem;
padding-bottom: 3rem;
background-color: #f7f7f7;
}
.card {
float: left;
width: 33.333%;
padding: .75rem;
margin-bottom: 2rem;
border: 1px solid #efefef;
text-align: center;
}
.card > img {
margin-bottom: .75rem;
border-radius: 100px;
}
.card-text {
font-size: 85%;
}
index.js:
import './index.css';
import React from 'react';
import { render } from 'react-dom';
import App from './App';
render(<App />, document.getElementById('app'));
public文件夹:
index.html:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<link rel="stylesheet" href="./bootstrap.css">
</head>
<body>
<div id="app"></div>
</body>
</html>
bootstrap.css :下载过来的