react 项目实战(五)渲染用户列表
现在我们需要一个页面来展现数据库中记录的用户。
在/src/pages下新建UserList.js文件。
创建并导出UserList组件:
import React from 'react';
class UserList extends React.Component {
render () {
return (
...
);
}
}
export default UserList;
当页面加载的时候需要调用接口来获取用户列表,并把获取到的用户列表数据存放到组件的state中(this.state.userList):
class UserList extends React.Component {
constructor (props) {
super(props);
this.state = {
userList: []
};
}
componentWillMount () {
fetch('http://localhost:8000/user')
.then(res => res.json())
.then(res => {
this.setState({
userList: res
});
});
}
render () { ... }
}
在render方法中,使用数组的map方法将用户数据渲染为一个表格:
src / pages / UserList.js
import React from 'react'; // 用户列表
class UserList extends React.Component {
// 构造器
constructor(props) {
super(props);
// 定义初始化状态
this.state = {
userList: []
};
} /**
* 生命周期
* componentWillMount
* 组件初始化时只调用,以后组件更新不调用,整个生命周期只调用一次
*/
componentWillMount(){
// 请求数据
fetch('http://localhost:8000/user')
.then(res => res.json())
.then(res => {
/**
* 成功的回调
* 数据赋值
*/
this.setState({
userList: res
});
});
} render() {
// 定义变量
const { userList } = this.state; return (
<div>
<header>
<h1>用户列表</h1>
</header> <main>
<table>
<thead>
<tr>
<th>用户ID</th>
<th>用户名</th>
<th>性别</th>
<th>年龄</th>
</tr>
</thead> <tbody>
{
userList.map((user) => {
return (
<tr key={user.id}>
<td>{user.id}</td>
<td>{user.name}</td>
<td>{user.gender}</td>
<td>{user.age}</td>
</tr>
);
})
}
</tbody>
</table>
</main>
</div>
);
}
} export default UserList;
在/src/index.js文件中添加指向这个页面的路由,并在/src/pages/Home.js中加入相应的链接:
src / index.js
// 配置路由
import React from 'react';
import ReactDOM from 'react-dom';
// 引入react-router
import { Router, Route, hashHistory } from 'react-router';
import HomePage from './pages/Home';
import UserAddPage from './pages/UserAdd'; // 添加用户页
import UserListPage from './pages/UserList' // 用户列表页 // 渲染
ReactDOM.render((
<Router history={hashHistory}>
<Route path="/" component={HomePage} />
<Route path="/user/add" component={UserAddPage} />
<Route path="/user/list" component={UserListPage} />
</Router>
), document.getElementById('root'));
src / pages / Home.js
import React from 'react';
import { Link } from 'react-router'; class Home extends React.Component {
// 构造器
constructor(props) {
super(props);
// 定义初始化状态
this.state = {};
} render() {
return (
<div>
<header>
<h1>Welcome</h1>
</header> <main>
<Link to="/user/list">用户列表</Link>
<br />
<Link to="/user/add">添加用户</Link>
</main>
</div>
);
}
} export default Home;
最后,我们可以在添加用户之后,使用this.context.router.push方法来跳转到用户列表页面:
npm i react-prop-types -S
src / pages / UserAdd.js
// 引入 prop-types
import PropTypes from 'prop-types'; class UserAdd extends React.Component {
handleSubmit (e) {
... fetch('http://localhost:8000/user', { ... })
.then((res) => res.json())
.then((res) => {
if (res.id) {
alert('添加用户成功');
this.context.router.push('/user/list'); // 跳转到用户列表页面
return;
} else {
alert('添加失败');
}
})
.catch((err) => console.error(err));
}
render () { ... }
} // 必须给UserAdd定义一个包含router属性的contextTypes
// 使得组件中可以通过this.context.router来使用React Router提供的方法
UserAdd.contextTypes = {
router: PropTypes.object.isRequired
};
完整代码 UserAdd.js:
import React from 'react';
import FormItem from '../components/FormItem';
// 高阶组件 formProvider表单验证
import formProvider from '../utils/formProvider';
// 引入 prop-types
import PropTypes from 'prop-types'; // 添加用户组件
class UserAdd extends React.Component {
// 按钮提交事件
handleSubmit(e){
// 阻止表单submit事件自动跳转页面的动作
e.preventDefault();
// 定义常量
const { form: { name, age, gender }, formValid} = this.props; // 组件传值
// 验证
if(!formValid){
alert('请填写正确的信息后重试');
return;
}
// 发送请求
fetch('http://localhost:8000/user', {
method: 'post',
// 使用fetch提交的json数据需要使用JSON.stringify转换为字符串
body: JSON.stringify({
name: name.value,
age: age.value,
gender: gender.value
}),
headers: {
'Content-Type': 'application/json'
}
})
// 强制回调的数据格式为json
.then((res) => res.json())
// 成功的回调
.then((res) => {
// 当添加成功时,返回的json对象中应包含一个有效的id字段
// 所以可以使用res.id来判断添加是否成功
if(res.id){
alert('添加用户成功!');
this.context.router.push('/user/list'); // 跳转到用户列表页面
return;
}else{
alert('添加用户失败!');
}
})
// 失败的回调
.catch((err) => console.error(err));
} render() {
// 定义常量
const {form: {name, age, gender}, onFormChange} = this.props;
return (
<div>
<header>
<div>添加用户</div>
</header> <main>
<form onSubmit={(e) => this.handleSubmit(e)}>
<FormItem label="用户名:" valid={name.valid} error={name.error}>
<input
type="text"
value={name.value}
onChange={(e) => onFormChange('name', e.target.value)}/>
</FormItem> <FormItem label="年龄:" valid={age.valid} error={age.error}>
<input
type="number"
value={age.value || ''}
onChange={(e) => onFormChange('age', e.target.value)}/>
</FormItem> <FormItem label="性别:" valid={gender.valid} error={gender.error}>
<select
value={gender.value}
onChange={(e) => onFormChange('gender', e.target.value)}>
<option value="">请选择</option>
<option value="male">男</option>
<option value="female">女</option>
</select>
</FormItem>
<br />
<input type="submit" value="提交" />
</form>
</main>
</div>
);
}
} // 必须给UserAdd定义一个包含router属性的contextTypes
// 使得组件中可以通过this.context.router来使用React Router提供的方法
UserAdd.contextTypes = {
router: PropTypes.object.isRequired
}; // 实例化
UserAdd = formProvider({ // field 对象
// 姓名
name: {
defaultValue: '',
rules: [
{
pattern: function (value) {
return value.length > 0;
},
error: '请输入用户名'
},
{
pattern: /^.{1,4}$/,
error: '用户名最多4个字符'
}
]
},
// 年龄
age: {
defaultValue: 0,
rules: [
{
pattern: function(value){
return value >= 1 && value <= 100;
},
error: '请输入1~100的年龄'
}
]
},
// 性别
gender: {
defaultValue: '',
rules: [
{
pattern: function(value) {
return !!value;
},
error: '请选择性别'
}
]
}
})(UserAdd); export default UserAdd;
这样我们在添加用户之后就可以立即在列表中看到最新添加的用户了:

react 项目实战(五)渲染用户列表的更多相关文章
- React项目实战:react-redux-router基本原理
React相关 React 是一个采用声明式,高效而且灵活的用来构建用户界面的框架. JSX 本质上来讲,JSX 只是为React.createElement(component, props, .. ...
- miniFTP项目实战五
项目简介: 在Linux环境下用C语言开发的Vsftpd的简化版本,拥有部分Vsftpd功能和相同的FTP协议,系统的主要架构采用多进程模型,每当有一个新的客户连接到达,主进程就会派生出一个ftp服务 ...
- react 项目实战(七)用户编辑与删除
添加操作列 编辑与删除功能都是针对已存在的某一个用户执行的操作,所以在用户列表中需要再加一个“操作”列来展现[编辑]与[删除]这两个按钮. 修改/src/pages/UserList.js文件,添加方 ...
- 【招聘App】—— React/Nodejs/MongoDB全栈项目:信息完善&用户列表
前言:最近在学习Redux+react+Router+Nodejs全栈开发高级课程,这里对实践过程作个记录,方便自己和大家翻阅.最终成果github地址:https://github.com/66We ...
- react 项目实战(二)创建 用户添加 页面 及 fetch请求 json-server db.json -w -p 8000
1.安装 路由 npm install -S react-router@3.x 2.新增页面 我们现在的应用只有一个Hello React的页面,现在需要添加一个用于添加用户的页面. 首先在/src目 ...
- react 项目实战(十)引入AntDesign组件库
本篇带你使用 AntDesign 组件库为我们的系统换上产品级的UI! 安装组件库 在项目目录下执行:npm i antd@3.3.0 -S 或 yarn add antd 安装组件包 执行:npm ...
- react 项目实战(九)登录与身份认证
SPA的鉴权方式和传统的web应用不同:由于页面的渲染不再依赖服务端,与服务端的交互都通过接口来完成,而REASTful风格的接口提倡无状态(state less),通常不使用cookie和sessi ...
- react 项目实战(八)图书管理与自动完成
图书管理 src / pages / BookAdd.js // 图书添加页 /** * 图书添加页面 */ import React from 'react'; // 布局组件 import H ...
- Omi实战-QQ附近用户列表Web页
原文地址https://github.com/AlloyTeam/omi/blob/master/docs/cn_pr_nearby.md 写在前面 Omi很适合大型复杂的Web页面开发,例如一些We ...
随机推荐
- 【Gambit】Gambit使用教程
第一章 Gambit使用 Gambit介绍 网格的划分使用Gambit软件,首先要启动Gambit,在Dos下输入Gambit <filemane>,文件名如果已经存在,要加上参数-old ...
- 迅为I.MX6DL开发板飞思卡尔Freescale Cortex A9 迅为-iMX6双核核心板
核心板参数 尺寸: 51mm*61mm CPU: Freescale Cortex-A9 双核精简版 i.MX6DL,主频 1.2 GHz 内存: 1GB DDR3 存储: 8GB EMMC 存储 E ...
- Divide and Conquer_1.最大连续子数组
给定一个数组,求它的一个子数组,使其求和最大. 这个问题的应用:给定一只股票很多天的价格,计算从哪天买进哪天卖出能获得最大利润. 给定 prices:100 113 98 87 65 ...
- Parker Gear Pump - Gear Pump Seal Is More O-Ring: Role
Parker Gear Pump introduction Gear pump lip seal is mainly used in reciprocating dynamic seals. C ...
- c++ 回调的实现
什么是回调?通常发生在需要两个角色即调用者与实现者的情形上,即我们希望当产生某个事件时,调用实现者定义的某个函数.当然这个概念很大,不是说操作系统的信号量,条件变量什么的,是在语言级别实现,如一个Fr ...
- (C/C++学习)17.bitset(位操作)
说明:bitset 就像 vector 一样,是 C++ 的一个类模板库,用来对一个数的二进制位进行管理.判断等操作,使用时需要包含头文件 #include<bitset>. 1.声明及定 ...
- 笔试算法题(07):还原后序遍历数组 & 半翻转英文句段
出题:输入一个整数数组,判断该数组是否符合一个二元查找树的后序遍历(给定整数数组,判定其是否满足某二元查找树的后序遍历): 分析:利用后序遍历对应到二元查找树的性质(序列最后一个元素必定是根节点,从左 ...
- navicat连接mysql8报错,错误提示为1251,原因及解决步骤
一.错误原因: MySQL8.0版本的加密方式和MySQL5.0的不一样,连接会报错. 二.解决步骤: 1.在linux虚拟机上登录mysql 2.更改加密方式: ALTER USER 'root'@ ...
- win7 x64安装glpk
下载glpk,下载地址:http://ftp.gnu.org/gnu/glpk/
- Spider-Python爬虫之聚焦爬虫与通用爬虫的区别
为什么要学习爬虫? 学习爬虫,可以私人订制一个搜索引擎. 大数据时代,要进行数据分析,首先要有数据源. 对于很多SEO从业者来说,从而可以更好地进行搜索引擎优化. 什么是网络爬虫? 模拟客户端发送网络 ...