• 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;

    这样我们在添加用户之后就可以立即在列表中看到最新添加的用户了:

  • 相关阅读:
    面试题:找出数组中只出现一次的2个数(异或的巧妙应用)(出现3次)
    线段树 | 第1讲 (给定区间求和)(转)
    C++中的静态多态和动态多态(转)
    ARP与RARP详细解析(转)
    排序算法之归并排序
    byte数组使用Arrays.asList转换List出错
    排序算法之希尔排序
    排序算法之冒泡排序、选择排序、插入排序
    Tomcat配置优化
    内连接、左外连接、右外连接、全外连接、交叉连接
  • 原文地址:https://www.cnblogs.com/crazycode2/p/8470327.html
Copyright © 2020-2023  润新知