Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

React 实践项目 (四) #9

Open
Yuicon opened this issue Jul 22, 2017 · 0 comments
Open

React 实践项目 (四) #9

Yuicon opened this issue Jul 22, 2017 · 0 comments

Comments

@Yuicon
Copy link
Member

Yuicon commented Jul 22, 2017

React在Github上已经有接近70000的 star 数了,是目前最热门的前端框架。而我学习React也有一段时间了,现在就开始用 React+Redux 进行实战!

上回说到使用Redux-saga 管理 Redux 应用异步操作,应用还是只有一个首页.现在开始构建一个新的投稿页面并使用 React-Router 进行路由管理.

React 实践项目 (一)

React 实践项目 (二)

React 实践项目 (三)

React 实践项目 (四)

React 实践项目 (五)

- 首先我们来构建投稿页面

创建 src/containers/SubmitEntry.js

/**
 * Created by Yuicon on 2017/7/13.
 * https://github.com/Yuicon
 */
import React, {Component} from 'react';
import {Button, Form, Input, Switch, Notification} from "element-react";
import {connect} from "react-redux";
import {createEntryAction} from '../../redux/action/entries';
import './SubmitEntry.css';

@connect(
  (state) => {
    return ({
      entries: state.entries,
    });
  },
  {createEntryAction: createEntryAction}
)
export default class SubmitEntry extends Component {

  constructor(props) {
    super(props);

    this.state = {
      form: {
        title: '',
        content: '',
        original: true,
        originalUrl: null,
        english: false,
        type: 'article',
      },
    loading: false,
    };
  }

  componentWillReceiveProps(nextProps) {
    if (nextProps.entries.get('saveSuccess')) {
      Notification.success({
        title: '成功',
        message: '投稿成功',
        duration: 1500
      });
      this.setState({form: {
        title: '',
        content: '',
        original: true,
        originalUrl: null,
        english: false,
        type: 'article',
      }});
    } else if (nextProps.entries.get('error')) {
      Notification.error({
        title: '错误',
        message: nextProps.entries.get('error'),
        type: 'success',
        duration: 1500
      });
    }
    this.setState({loading: false});
  }

  handleSubmit = () => {
    this.props.createEntryAction(this.state.form);
    this.setState({loading: true});
  };

  handleChange = (key, value) => {
    this.setState({
      user: Object.assign(this.state.form, {[key]: value})
    });
  };

  render(){
    return(
      <div className="SubmitEntry-container">
        <div className="head">
          <h2>推荐文章到掘金</h2>
          <p>感谢分享,文章的审核时间约1-2个工作日</p>
        </div>
        <div className="entry-form">
          <Form model={this.state.form} labelWidth="80" onSubmit={this.handleSubmit}>
            <Form.Item label="分享网址">
              <Input value={this.state.form.originalUrl} onChange={this.handleChange.bind(this, 'originalUrl')}/>
            </Form.Item>
            <Form.Item label="标题">
              <Input value={this.state.form.title} onChange={this.handleChange.bind(this, 'title')}/>
            </Form.Item>
            <Form.Item label="描述">
              <Input value={this.state.form.content} onChange={this.handleChange.bind(this, 'content')}/>
            </Form.Item>
            <Form.Item >
              <Switch
                value={this.state.form.original}
                onChange={this.handleChange.bind(this, 'original')}
                onText="原创"
                offText="转载">
              </Switch>
            </Form.Item>
            <Form.Item >
              <Switch
                value={this.state.form.english}
                onChange={this.handleChange.bind(this, 'english')}
                onText="英文"
                offText="中文">
              </Switch>
            </Form.Item>
            <Form.Item >
              <Button type="primary" onClick={this.handleSubmit} loading={this.state.loading}>
                发布
              </Button>
            </Form.Item>
          </Form>
        </div>
      </div>
    )
  }
}

相关的Redux部分已经讲过.就不重复介绍了,感兴趣的可以查看示例代码

  • 页面创建好了,开始使用 React-Router 管理路由

  • 首先是添加依赖

编辑 package.json

     // react-router-dom 包含 react-router
    "react-router-dom": "^4.1.1",
  • 编辑 App.js
/**
 * Created by Yuicon on 2017/6/25.
 */
import React, { Component } from 'react';
import {BrowserRouter as Router,Route} from 'react-router-dom'
import './App.css';
import Index from "../Index/Index";
import Header from "../Header/Header";
import SubmitEntry from "../SubmitEntry/SubmitEntry";

export default class App extends Component {

  render(){
    return(
    <Router>
      <div className="App">
        <Route component={Header}/>
        <Route exact path="/" component={Index}/>
        <Route exact path="/submit-entry" component={SubmitEntry}/>
      </div>
    </Router>
    )
  }

}

Router:

Router 一共有三种,我们采用的是常用的 browserHistory

browserHistory h5的history
hashHistory 老版本浏览器的history
memoryHistory node环境下的history,存储在memory中

Route :

每个 Route 标签都对应一个UI页面,它的职责就是当页面的访问地址与 Route 上的 path 匹配时,就渲染出对应的 UI 界面。
<Route component={Header}/> 是没有 path 的,这意味着在每个页面都会渲染出 Header 组件.

exact :

Route 上的 exact props 表示采用严格匹配,页面的访问地址与 Route 上的 path 必须一样
<Route exact path="/" component={Index}/> 只会匹配 '/' , 不会匹配 '/submit-entry'
<Route path="/" component={Index}/> 会匹配所有 '/' 开头的路径

history:

常用方法

push(path, [state]) 在历史堆栈信息里加入一个新条目。
常用于页面跳转,如: this.props.history.push('/'); 跳转至首页

replace(path, [state]) 在历史堆栈信息里替换掉当前的条目
与 push 的区别是无法通过历史堆栈返回跳转前的页面

goBack() 等同于浏览器的后退键

match:

match 对象包含了 Route 如何与 URL 匹配的信息,具有以下属性:

params: object 路径参数,通过解析 URL 中的动态部分获得键值对

isExact: bool 为 true 时,整个 URL 都需要匹配

path: string 用来匹配的路径模式,用于创建嵌套的

url: string URL 匹配的部分,用于嵌套的

常用于获取路径中的参数
有这样一个路由 <Route path="/:id" component={Child}/>
在 Child 中可以这样获取到 id 参数 this.props.match.params.id

  • 结语

现在我们得到了一个可以见人的应用了,剩下的大部分是一些业务代码。为了检验效果当然是选择部署到服务器。下篇文章将会介绍利用 nginx 的 docker 镜像部署 React 应用。
完整项目代码地址:https://github.com/DigAg/digag-pc-react

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant