【React全家桶入门之三】基本的用户添加

来源:互联网 发布:淘宝店铺装修页头图片 编辑:程序博客网 时间:2024/05/17 02:35

新增页面

我们现在的应用只有一个Hello React的页面,现在需要添加一个用于添加用户的页面。

首先在/src目录下新增一个pages目录,用于存放渲染页面的组件。

然后在/src/pages中新增一个UserAdd.js文件。

Tips: 关于文件的命名,我采用这样的方式:[模块][功能].xxx,上面是一个添加用户的页面,所以模块是User,功能是Add,良好的命名风格可以让你的项目、代码更容易维护(这里由于是react的一个组件,所以使用大写开头的大驼峰命名法)。

在这个文件中写入一个基本的React组件:

import React from 'react';class UserAdd extends React.Component {  render () {    return (      <div>User add page.</div>    );  }}export default UserAdd;
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11

配置路由

我们需要使用react-router提供的路由组件来控制当前路由下页面应该渲染的组件。

修改/src/index.js为:

import React from 'react';import ReactDOM from 'react-dom';import { Router, Route, hashHistory } from 'react-router';import UserAddPage from './pages/UserAdd';ReactDOM.render((  <Router history={hashHistory}>    <Route path="/user/add" component={UserAddPage}/>  </Router>), document.getElementById('app'));
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10

打开浏览器的http://localhost:8000发现页面一片空白,在控制台中可以看到一个错误信息: 

这是因为我们只配了一个/user/add的路由,我们来访问一下http://localhost:8000/#/user/add看看 
 
新页面出来了。现在需要把上面的那个错误干掉:新建一个主页,并在主页中添加一个链接链到添加用户的页面。

还是在/src/pages/中新建一个Home.js,写入代码:

import React from 'react';import { Link } from 'react-router';class Home extends React.Component {  render () {    return (      <div>        <header>          <h1>Welcome</h1>        </header>        <main>          <Link to="/user/add">添加用户</Link>        </main>      </div>    );  }}export default Home;
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20

然后在/src/index.js中添加一个指向Home的Route:

import HomePage from './pages/Home';ReactDOM.render((  <Router history={hashHistory}>    <Route path="/" component={HomePage}/>    <Route path="/user/add" component={UserAddPage}/>  </Router>), document.getElementById('app'));
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

 
首页已经可以正常访问了,并且点击添加用户也正确地跳转到了添加用户页面。

Q: 为什么我看到的url里有一个’#’? 
A: 这是由于我们给Router组件传入了hashHistory,url中’#’及’#’以后的部分属于hash,hash的变化并不会引起页面的重新刷新,而hashHistory会监听hash的变化使得Router组件能够根据url渲染出正确的组件。除了hash History之外还有browserHistory和memoryHistory。使用browserHistory可以让url变得像标准的url一样(没有#),但是需要在后端做一些特殊处理;memoryHistory是用于做服务端渲染时使用的。

Q: 为什么Home.js里要用Link组件而不是一个标准的a标签? 
A: 上面说了,我们使用了hashHistory,正确的页面url中应该都是有一个’#’的,如果直接使用a标签,你需要这么写:<a href=”/#/user/add”>添加用户</a>。但是如果我们想要换成browserHistory,就需要把所有标签中的’#’去掉。使用react-router提供的Link组件可以让我们无视history之间的差异性,直接写标准的路由”/user/add”就可以了。此外,由于我们写的是单页面应用(SPA),Link组件会阻止页面的跳转(仅仅只是改变了url,然后改变了渲染的组件)。

编写页面

现在开始编写添加用户的逻辑。

在上一篇中,我们定义了User的结构为:

{  "id": 10000,  "name": "一韬",  "age": 25,  "gender": "male"}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

在新建的时候,我们需要使用post方式将新用户的name、age、gender发送给接口http://localhost:3000/user,因此这个添加用户的页面需要提供一个包含上述3个字段控件的表单:

class UserAdd extends React.Component {  render () {    return (      <div>        <header>          <h1>添加用户</h1>        </header>        <main>          <form>            <label>用户名:</label>            <input type="text"/>            <br/>            <label>年龄:</label>            <input type="number"/>            <br/>            <label>性别:</label>            <select>              <option value="">请选择</option>              <option value="male"></option>              <option value="female"></option>            </select>            <br/>            <br/>            <input type="submit" value="提交"/>          </form>        </main>      </div>    );  }}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31

现在我们的页面是这个样子: 

获取表单的值

现在我们可以在表单中填写数据了,但是还不能获取到我们输入的值。

在React中处理表单有些不一样,由于React提倡“单向数据流”,React中的表单并不提供双向数据绑定的功能,我们需要给表单绑定它的value,然后提供一个onChange的处理方法来更新value的值。

这里我们使用组件的state来维护表单的值,在onChange的时候使用setState来更新值,最后,在表单提交事件被触发的时候,我们输出state来观察最终获得的表单值:

class UserAdd extends React.Component {  constructor () {    super();    this.state = {      name: '',      age: 0,      gender: ''    };  }  handleValueChange (field, value, type = 'string') {    // 由于表单的值都是字符串,我们可以根据传入type为number来手动转换value的类型为number类型    if (type === 'number') {      value = +value;    }    this.setState({      [field]: value    });  }  handleSubmit (e) {    // 阻止表单submit事件自动跳转页面的动作    e.preventDefault();    alert(JSON.stringify(this.state));  }  render () {    const {name, age, gender} = this.state;    return (      <div>        <header>          <h1>添加用户</h1>        </header>        <main>          <form onSubmit={(e) => this.handleSubmit(e)}>            <label>用户名:</label>            <input type="text" value={name} onChange={(e) => this.handleValueChange('name', e.target.value)}/>            <br/>            <label>年龄:</label>            <input type="number" value={age || ''} onChange={(e) => this.handleValueChange('age', e.target.value, 'number')}/>            <br/>            <label>性别:</label>            <select value={gender} onChange={(e) => this.handleValueChange('gender', e.target.value)}>              <option value="">请选择</option>              <option value="male"></option>              <option value="female"></option>            </select>            <br/>            <br/>            <input type="submit" value="提交"/>          </form>        </main>      </div>    );  }}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55

在页面中填写表单,点提交后可以看到如下界面: 

调用接口创建用户

拿到了表单数据,我们离目标已经很近了,就差最后一步:把表单的值通过接口提交

调用接口可以有很多方法:Ajax、表单提交、fetch。

由于直接使用表单提交会引起页面的跳转,这不符合我们单页应用的原则。这里我们使用比Ajax更先进易用的fetch。

修改/pages/UserAdd.js中的handleSubmit方法:

  handleSubmit (e) {    e.preventDefault();    const {name, age, gender} = this.state;    fetch('http://localhost:3000/user', {      method: 'post',      // 使用fetch提交的json数据需要使用JSON.stringify转换为字符串      body: JSON.stringify({        name,        age,        gender      }),      headers: {        'Content-Type': 'application/json'      }    })      .then((res) => res.json())      .then((res) => {        // 当添加成功时,返回的json对象中应包含一个有效的id字段        // 所以可以使用res.id来判断添加是否成功        if (res.id) {          alert('添加用户成功');          this.setState({            name: '',            age: 0,            gender: ''          });        } else {          alert('添加失败');        }      })      .catch((err) => console.error(err));  }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33

填写表单然后点击提交后,可以看到弹出一个添加成功的提示框: 

打开http://localhost:3000/user查看所有用户列表,发现用户已经被添加进去了: 

至此就完成了基本的添加用户功能~