现在我们需要一个页面来展现数据库中记录的用户。

/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 项目实战(五)渲染用户列表的更多相关文章

  1. React项目实战:react-redux-router基本原理

    React相关 React 是一个采用声明式,高效而且灵活的用来构建用户界面的框架. JSX 本质上来讲,JSX 只是为React.createElement(component, props, .. ...

  2. miniFTP项目实战五

    项目简介: 在Linux环境下用C语言开发的Vsftpd的简化版本,拥有部分Vsftpd功能和相同的FTP协议,系统的主要架构采用多进程模型,每当有一个新的客户连接到达,主进程就会派生出一个ftp服务 ...

  3. react 项目实战(七)用户编辑与删除

    添加操作列 编辑与删除功能都是针对已存在的某一个用户执行的操作,所以在用户列表中需要再加一个“操作”列来展现[编辑]与[删除]这两个按钮. 修改/src/pages/UserList.js文件,添加方 ...

  4. 【招聘App】—— React/Nodejs/MongoDB全栈项目:信息完善&用户列表

    前言:最近在学习Redux+react+Router+Nodejs全栈开发高级课程,这里对实践过程作个记录,方便自己和大家翻阅.最终成果github地址:https://github.com/66We ...

  5. react 项目实战(二)创建 用户添加 页面 及 fetch请求 json-server db.json -w -p 8000

    1.安装 路由 npm install -S react-router@3.x 2.新增页面 我们现在的应用只有一个Hello React的页面,现在需要添加一个用于添加用户的页面. 首先在/src目 ...

  6. react 项目实战(十)引入AntDesign组件库

    本篇带你使用 AntDesign 组件库为我们的系统换上产品级的UI! 安装组件库 在项目目录下执行:npm i antd@3.3.0 -S 或 yarn add antd 安装组件包 执行:npm ...

  7. react 项目实战(九)登录与身份认证

    SPA的鉴权方式和传统的web应用不同:由于页面的渲染不再依赖服务端,与服务端的交互都通过接口来完成,而REASTful风格的接口提倡无状态(state less),通常不使用cookie和sessi ...

  8. react 项目实战(八)图书管理与自动完成

    图书管理 src / pages / BookAdd.js   // 图书添加页 /** * 图书添加页面 */ import React from 'react'; // 布局组件 import H ...

  9. Omi实战-QQ附近用户列表Web页

    原文地址https://github.com/AlloyTeam/omi/blob/master/docs/cn_pr_nearby.md 写在前面 Omi很适合大型复杂的Web页面开发,例如一些We ...

随机推荐

  1. java SSL 邮件发送

    Properties props = new Properties(); props.put("mail.smtp.host", smtp); props.put("ma ...

  2. shellinabox的安装使用

    一.简介 Shell In A Box(发音是shellinabox)是一款基于Web的终端模仿器,由Markus Gutschke开辟而成.它有内置的Web办事器,在指定的端口上作为一个基于Web的 ...

  3. Linux Mint 教程

    Linux Mint 安装文本编辑软件 sudo apt-get install gedit linux操作系统上面开发程序, 光有了gcc 是不行的它还需要一个   build-essential软 ...

  4. Axure 9 面板折叠显示隐藏

    1  首先放置一个面板1作为点击事件: 2  另外一个面板2或者其他组建,将其设置为动态面板,然后隐藏 3  给面板1添加如下事件,即可: 4  我们点击面板1,可以实现展开隐藏面板2的动态效果

  5. 最小生成树Prim算法 Kruskal算法

    Prim算法(贪心策略)N^2 选定图中任意定点v0,从v0开始生成最小生成树 树中节点Va,树外节点Vb 最开始选一个点为Va,其余Vb, 之后不断加Vb到Va最短距离的点 1.初始化d[v0]=0 ...

  6. Java基础(十一)--Serializable和Externalizable接口实现序列化

    序列化在日常开发中经常用到,特别是涉及到网络传输的时候,例如调用第三方接口,通过一个约定好的实体进行传输,这时你必须实现序列 化,这些都是大家都了解的内容,所以文章也会讲一下序列化的高级内容. 序列化 ...

  7. Less简介及安装

    CSS的短板 作为前端学习者的我们 或多或少都要学些 CSS ,它作为前端开发的三大基石之一,时刻引领着 Web 的发展潮向. 而 CSS 作为一门标记性语言,可能 给初学者第一印象 就是简单易懂,毫 ...

  8. php基础查找算法

    1.顺序查找 function line_search($array,$tar) { if(!is_array($array) || count($array) < 1) return fals ...

  9. SQLSTATE[23000]报错

    SQLSTATE[23000]: Integrity constraint violation: 1052 Column 'id' in order clause is ambiguous 这个问题在 ...

  10. glibc库函数,系统调用API

    glibc封装了大部分系统API,我们一般都是使用glibc封装的接口进行系统调用,碰到一些没有封装的接口,可以通过这个 函数syscall 进行系统调用.   /* Invoke `system c ...