The development of cnode website by dva

Keywords: Javascript React AWS Java Python

Complete registration logic and personal center page

1 reg component validation logic

The same validation rules as login

import React , { Component }from 'react';
import PropTypes from 'prop-types';
import { connect } from 'dva';
import { Form, Icon, Input, Button, Checkbox,message} from 'antd';
import { routerRedux } from 'dva/router';

const backgroundImage = require('../assets/back.jpg');
const FormItem = Form.Item;

class Reg extends Component{

  handleSubmit = (e) => {
    e.preventDefault();
    const {dispatch} = this.props
    this.props.form.validateFields((err, values) => {
   if (!err) {
     const { userName,password,againPwd } = values
     if (password === againPwd) {
       dispatch({ type: 'user/reg', payload: { userName,password } })
     } else {
       message.warning('The passwords you entered are different');
     }

   }
 });
}

    render() {
      const { getFieldDecorator,getFieldError } = this.props.form
      return (
        <div  style={styles.form}>
           <h1>register</h1>
           <Form onSubmit={this.handleSubmit}>
           <FormItem>
              {getFieldDecorator('userName', {
              rules: [{ required: true, message: 'enter one user name' },
                  {max:20,message: 'Maximum length cannot exceed 20'}],
              })(
                 <Input prefix={<Icon type="user" style={{ color: 'rgba(0,0,0,.25)' }} />} placeholder="User name" />
              )}
           </FormItem>
           <FormItem>
           {getFieldDecorator('password', {
            rules: [{ required: true, message: 'Please input a password' },
                  {pattern:/^(?![^a-zA-Z]+$)(?!\D+$)/,message: 'Password must contain numbers and letters'},
                {min:6,message: 'Minimum length is 6 bits'},
                {max:12,message: 'Maximum length 12 bits'},],
             })(
            <Input prefix={<Icon type="lock" style={{ color: 'rgba(0,0,0,.25)' }} />} type="password" placeholder="Password" />
             )}
           </FormItem>
           <FormItem>
           {getFieldDecorator('againPwd', {
            rules: [{ required: true, message: 'Please enter the confirmation password' },
                  {pattern:/^(?![^a-zA-Z]+$)(?!\D+$)/,message: 'Password must contain numbers and letters'},
                {min:6,message: 'Minimum length is 6 bits'},
                {max:12,message: 'Maximum length 12 bits'},],
             })(
            <Input prefix={<Icon type="lock" style={{ color: 'rgba(0,0,0,.25)' }} />} type="password" placeholder="Enter password again" />
             )}
           </FormItem>
           <FormItem>
               <Button block type="primary" onClick={this.handleSubmit}>
                 //register
               </Button>
             <a>Forget password</a>
             //Or log in</a>
           </FormItem>
         </Form>

    </div>
      )

    }
    componentWillMount () {
      if(this.props.state.user.isLogin) {
         this.props.dispatch(routerRedux.push('/'))
      }
   }
}

const styles = {
  form: {
    maxWidth: '400px',
    margin: '0 auto',
    paddingTop: '100px',
  }
};

Reg.propTypes = {

};

function mapStateToProps(state) {
  return {
    state
  }
}

// export default ListData;
export default connect(mapStateToProps)(Form.create()(Reg));

2. User service joins the registration api

If you have backstage, please change it into your own

export function regUser({ userName,password}) {
  return {
    userName: `${userName}`,
    password: `${password}`
  };
}

3. Add registration action to usermodel

It should be registered, so the data in state is not processed. By the way, the exit login action has also been done

import * as userService from '../services/userService';
import { routerRedux } from 'dva/router';


export default {
  namespace: 'user',
  state:{
      isLogin:false,
      user:{}
  },
    effects: {
        *login({ payload: { userName,password } }, { call, put }) {
            const result = yield call(userService.getUser, { userName,password })
               yield put({
               type: 'updateUser',
                 payload: {
                     result
                 }
             })
             yield put(routerRedux.push('/'))
        },
        *reg({ payload: { userName,password } }, { call, put }) {
            const result = yield call(userService.regUser, { userName,password })
             yield put(routerRedux.push('/login'))
        },
        *logOut({ payload: {} },{ call, put }){
          yield put({type: 'userOut'})
        }
  },

  reducers: {
    'updateUser'(state, { payload: data }) {
        let r = data.result
        return {isLogin:true,user:r}
    },
    'userOut'(state) {
        return {isLogin:false,user:{}}
    }
  },

};

4. Create the person component to show the data of the personal Center

import React , { Component }from 'react';
import { Card, Col, Row , Timeline, Icon} from 'antd';
import PropTypes from 'prop-types';
import { connect } from 'dva';
import './my.css';


class Person extends Component{

    render() {
      return (
        <div style={{ background: '#ECECEC', padding: '30px' }}>
           <Row gutter={16}>
             <Col span={8}>
               <Card title="Personal information" bordered={false}>
                <p>Gender:{this.props.state.user.user.sex}</p>
                <p>Work:{this.props.state.user.user.job}</p>
                <p>Interest:{this.props.state.user.user.like}</p>
                <p>Company:{this.props.state.user.user.work}</p>
                <p>Work address:{this.props.state.user.user.location}</p>
                <p>Blog:{this.props.state.user.user.blog}</p>
                <p>Introduction:{this.props.state.user.user.desp}</p>
               </Card>
             </Col>
             <Col span={8}>
               <Card title="dva Course progress" bordered={false}>
                  <Timeline>
                      <Timeline.Item dot={<Icon type="check-circle-o" style={{ fontSize: '16px' }} />} color="green">1 dva Initialization project, navigation menu</Timeline.Item>
                      <Timeline.Item dot={<Icon type="check-circle-o" style={{ fontSize: '16px' }} />} color="green">2 List data rendering</Timeline.Item>
                      <Timeline.Item dot={<Icon type="check-circle-o" style={{ fontSize: '16px' }} />} color="green">3 react-markdown Render detail page</Timeline.Item>
                      <Timeline.Item dot={<Icon type="check-circle-o" style={{ fontSize: '16px' }} />} color="green">4 Data classification label</Timeline.Item>
                      <Timeline.Item dot={<Icon type="check-circle-o" style={{ fontSize: '16px' }} />} color="green">5 Login registration and other pages</Timeline.Item>
                      <Timeline.Item dot={<Icon type="check-circle-o" style={{ fontSize: '16px' }} />} color="green">6 Login logic and routing authority</Timeline.Item>
                      <Timeline.Item dot={<Icon type="check-circle-o" style={{ fontSize: '16px' }} />} color="green">7 Registration logic</Timeline.Item>
                      <Timeline.Item dot={<Icon type="clock-circle-o" style={{ fontSize: '16px' }} />} color="red">8 Course summary</Timeline.Item>
                  </Timeline>
               </Card>
             </Col>
             <Col span={8}>
               <Card title="My post" bordered={false}>
                 <p>1.Server migration to aws Japanese computer room</p>
                 <p>2.Learn from good examples java</p>
                 <p>3.Settle python</p>
                 <p>4.Upper hand react</p>
                 <p>5.Development of artificial intelligence</p>
               </Card>
             </Col>
           </Row>
         </div>
      )
    }

    componentWillMount () {

   }
}


Person.propTypes = {
    id: PropTypes.string.isRequired,
};

function mapStateToProps(state) {
  return {
      state
  };
}

// export default ListData;
export default connect(mapStateToProps)(Person);

5 personal center page create MyPage

Person component used


import React from 'react';
import { connect } from 'dva';
import Header from '../components/Header';
import Person from '../components/Person';

function MyPage() {
  return (
    <div>
      <Header keys={['my']}/>
      <div style={{paddingTop:20,paddingLeft:100,paddingRight:100,paddingBottom:50}}>
          <Person/>
      </div>
    </div>
  );
}

MyPage.propTypes = {
};

export default connect()(MyPage);

6 personal center needs to add authority judgment

Using AuthRouter in routing

import React from 'react';
import { Router, Route, Switch } from 'dva/router';
import IndexPage from './routes/IndexPage';
import DetailPage from './routes/DetailPage';
import NewUserPage from './routes/NewUserPage';
import ApiPage from './routes/ApiPage';
import AboutPage from './routes/AboutPage';
import LoginPage from './routes/LoginPage';
import RegPage from './routes/RegPage';
import MyPage from './routes/MyPage';
import AuthRouter from './components/AuthRouter';

function RouterConfig({ history }) {
  return (
    <Router history={history}>
      <Switch>
        <Route path="/" exact component={IndexPage} />
        <Route path="/detail/:id" exact component={DetailPage} />
        <Route path="/into" exact component={NewUserPage} />
        <Route path='/about' component={AboutPage}/>
        <Route path="/login" exact component={LoginPage} />
        <Route path="/reg" exact component={RegPage} />
        <AuthRouter path='/api' component={ApiPage}></AuthRouter>
        <AuthRouter path='/my' component={MyPage}></AuthRouter>
      </Switch>
    </Router>
  );
}

export default RouterConfig;

7 modify the Header component, dynamically display login, registration, personal center, exit login

import React from 'react';
import { Menu, Icon, Input,Avatar  } from 'antd';
import PropTypes from 'prop-types';
import {Link} from 'dva/router';
import { connect } from 'dva';

const Search = Input.Search;

const Header = ({dispatch,state,keys}) => {
const isLoged = state.user.isLogin

function MyHeader() {
  function logOut(e){
    e.preventDefault();
    console.log('logout');
    dispatch({ type: 'user/logOut',payload: {}})
  }
  if(isLoged){
    return <Menu
         selectedKeys={keys}
         mode="horizontal"
       >
       <Menu.Item key="node" disabled>
         <Icon type="tag" />CNODE
       </Menu.Item>
       <Menu.Item key="search">
         <Search placeholder="input text search"
         onSearch={v => console.log(v)}
         enterButton/>
       </Menu.Item>
         <Menu.Item key="index">
         <Link to="/"><Icon type="appstore" />home page</Link>
         </Menu.Item>
         <Menu.Item key="into">
           <Link to="/into"><Icon type="appstore" />getting started</Link>
         </Menu.Item>
         <Menu.Item key="api">
           <Link to="/api"><Icon type="appstore" />API</Link>
         </Menu.Item>
         <Menu.Item key="about">
          <Link to="/about"><Icon type="appstore" />about</Link>
         </Menu.Item>
        <Menu.Item key="my">
        <Avatar src="https://zos.alipayobjects.com/rmsportal/ODTLcjxAfvqbxHnVXCYX.png" />
          <span style={{fontSize:16}}><Link to="/my">{state.user.user.name}</Link></span>
        </Menu.Item>
        <Menu.Item key="logout">
         <Icon type="logout"/><span onClick={logOut}>Quit landing</span>
        </Menu.Item>
      </Menu>
  }else{
    return <Menu
         selectedKeys={keys}
         mode="horizontal"
       >
       <Menu.Item key="node" disabled>
         <Icon type="tag" />CNODE
       </Menu.Item>
       <Menu.Item key="search">
         <Search placeholder="input text search"
         onSearch={v => console.log(v)}
         enterButton/>
       </Menu.Item>
         <Menu.Item key="index">
         <Link to="/"><Icon type="appstore" />home page</Link>
         </Menu.Item>
         <Menu.Item key="into">
           <Link to="/into"><Icon type="appstore" />getting started</Link>
         </Menu.Item>
         <Menu.Item key="api">
           <Link to="/api"><Icon type="appstore" />API</Link>
         </Menu.Item>
         <Menu.Item key="about">
          <Link to="/about"><Icon type="appstore" />about</Link>
         </Menu.Item>
        <Menu.Item key="reg">
         <Link to="/reg"><Icon type="appstore" />register</Link>
       </Menu.Item>
       <Menu.Item key="login">
         <Link to="/login"><Icon type="appstore" />Land</Link>
       </Menu.Item>
      </Menu>
  }
}
return (
   <MyHeader/>
)


}

Header.propTypes = {
    keys: PropTypes.array.isRequired
};
function mapStateToProps(state) {
 return {
   state
 }
}

// export default ListData;
export default connect(mapStateToProps)(Header);

It's not easy to insist on completing the practical introduction course of dva. The whole function of cnode has been realized. The original website is authorized to log in with github. In this course, the background api is simulated to log in and register. Although it is fake data, it is enough for you to understand the interaction before and after. In the next lesson, I'd like to summarize and finish this course. I hope it will help you to learn react.

This is the end of today's course. Don't forget to pay attention to me. mike wants to do everything

Posted by RyanDev on Sat, 30 Nov 2019 16:58:12 -0800