React 实现路由导航

2019 Java 开发者跳槽指南.pdf (吐血整理)….>>>

React 实现路由导航

在使用React去实现web应用的导航功能,我们需要明白 

①菜单导航只是改变URL的状态 

②根据当前的URL显示菜单的当前状态。


下面我们先看一个小 Demo

故事背景:我们平常商城注册账号的时候,一般会有几个步骤,比如第一步 输入邮箱/手机号,第二步填写基本信息,第三步确认信息,完成注册。


React 实现路由导航

其实我们可以在浏览器的地址栏上看到变化,这也是 导航应用的一种。下面简单介绍一下这种做法。


app.js文件

import React from "react";
import _ from "lodash";
import { HashRouter as Router, Route, Link } from "react-router-dom";
import { Button, Steps, Form, Modal } from "antd";
import Step1 from "./Step1";
import Step2 from "./Step2";
import Step3 from "./Step3";

class App extends React.Component {
  state = {
    allValues: {},
  };

  pushUrl(path) {
    window.history.pushState(null""`/#${path}`);
    this.forceUpdate();
  }

  handleNext = () => {
    this.setState({
      allValues: {
        ...this.state.allValues,
        ...this.props.form.getFieldsValue(),
      },
    });
    const currentStep = this.getCurrentStep();
    if (currentStep < this.getSteps().length - 1) {
      this.pushUrl(this.getSteps()[currentStep + 1].path);
    } else {
      Modal.success({
        title"提交成功",
      });
    }
  };
  handleBack = () => {
    console.log("form values: "this.props.form.getFieldsValue());
    this.setState({
      allValues: {
        ...this.state.allValues,
        ...this.props.form.getFieldsValue(),
      },
    });
    const currentStep = this.getCurrentStep();
    if (currentStep > 0) {
      this.pushUrl(this.getSteps()[currentStep - 1].path);
    }
  };

  getCurrentStep() {
    const currentPath = document.location.hash.replace(/^#/"");
    return _.findIndex(this.getSteps(), { path: currentPath });
  }

  getSteps() {
    return [
      { title"验证邮件"path"/wizard/step/1"component: Step1 },
      { title"账号信息"path"/wizard/step/2"component: Step2 },
      { title"完成"path"/wizard/step/3"component: Step3 },
    ];
  }
  renderComponent = () => {
    const StepComponent = this.getSteps()[this.getCurrentStep()].component;
    return (
      <StepComponent form={this.props.form} allValues={this.state.allValues} />
    );
  };
  render() {
    if (!/^#/wizard/step/.test(document.location.hash)) {
      return (
        <Button type="primary" onClick={() => this.pushUrl("/wizard/step/1")}>
          创建账号
        </Button>
      );
    }
    return (
      <Router>
        <Form>
          <div style={{ width: "600px" }}>
            <h1>创建账号</h1>
            <Steps current={this.getCurrentStep()}>
              {this.getSteps().map(step => <Steps.Step title={step.title} />)}
            </Steps>

            <div className="step-container" style={{ margin: "40px 0" }}>
              <Route
                path="/wizard/step/:stepId"
                render={this.renderComponent}
              />
            </div>
            <div>
              <Button
                disabled={this.getCurrentStep() === 0}
                onClick={this.handleBack}
                style={{ marginRight: "20px" }}
              >
                上一步
              </Button>

              <Button onClick={this.handleNext} type="primary">
                {this.getCurrentStep() === this.getSteps().length - 1
                  ? "完成"
                  : "下一步"}
              </Button>
            </div>
          </div>
        </Form>
      </Router>
    );
  }
}
export default Form.create()(App);



对应的 三个小组件,放图

// Step1
import React, { Component } from "react";
import { Button, DatePicker, Form, Input, InputNumber, Select } from "antd";
import FormBuilder from "../c29/FormBuilder";

const Option = Select.Option;

const formMeta = {
  colontrue,
  columns1,
  elements: [{ key"email"label"Email"widget: Input }]
};

class Step1 extends Component {
  componentDidMount() {
    this.props.form.setFieldsValue(this.props.allValues);
  }
  render() {
    return (
      <div>
        <FormBuilder meta={formMeta} form={this.props.form} />
      </div>
    );
  }
}

export default Step1;
// Step2
import React, { Component } from "react";
import { Button, DatePicker, Form, Input, InputNumber, Select } from "antd";
import FormBuilder from "../c29/FormBuilder";

const Option = Select.Option;

const formMeta = {
  colontrue,
  columns1,
  elements: [
    { key"userName"label"用户名"widget: Input },
    { key"password"label"密码"widget: Input, type"password" },
    { key"birthday"label"生日"widget: DatePicker }
  ]
};

class Step2 extends Component {
  componentDidMount() {
    this.props.form.setFieldsValue(this.props.allValues);
  }
  render() {
    return (
      <div>
        <FormBuilder meta={formMeta} form={this.props.form} />
      </div>
    );
  }
}

export default Step2;
// Step3
import React, { Component } from "react";

class Step3 extends Component {
  render() {
    const { email, userName, birthday } = this.props.allValues;
    return (
      <div className="wizard-finish-step">
        <ul>
          <li>
            <label>Email:</label>
            <span>{email}</span>
          </li>
          <li>
            <label>用户名:</label>
            <span>{userName}</span>
          </li>
          <li>
            <label>生日:</label>
            <span>{birthday ? birthday.format("M月D日") : ""}</span>
          </li>
        </ul>
      </div>

    );
  }
}

export default Step3;


第一个写微信公众号,不想写Hello World,不知道呈现之后的效果是什么,明天再改样式吧。

原文始发于微信公众号(程序员思语):React 实现路由导航