练练手! TS + React 小项目(04 列表渲染 & 路由配置)

上一篇 中,我们为表单元素绑定了事件、封装了 Axios、向后端发送了 get 请求以及搭建了 mock server — 将请求转发到了本地,并返回了一个 json。接下来我们就用这个 response 渲染表单以及项目路由的配置。

列表渲染

兄弟组件间的通讯

/*
 ** src/components/employee/index.tsx
 */

class Employee extends Component {
  render() {
    return (
      <>
        <QueryForm />
        <Table columns={employeeColumns} className="table" />
      </>
    );
  }
}
复制代码

我们可以看到 Employee 分为 QueryFormTable 两个组件。数据返回在 QueryForm 中,那么如何用该数据渲染 Table 呢?

我们可以在他们的父组件(Employee)中添加一个状态,将状态绑定到 Table 上,然后为 QueryForm 添加一个回调 — 以控制该状态。

import { EmployeeResponse } from "../../interface/employee";

interface State {
  employee: EmployeeResponse;
}

class Employee extends Component<{}, State> {
  state: State = { employee: undefined };
  setEmployee = (employee: EmployeeResponse) => {
    this.setState({ employee });
  };
  render() {
    return (
      <>
        <QueryForm onDataChange={this.setEmployee} />
        <Table
          columns={employeeColumns}
          dataSource={this.state.employee}
          className="table"
        />
      </>
    );
  }
}
复制代码

这时,QueryForm 会有一个报错,因为 AntdForm 组件进行的封装在我们添加属性时会有兼容性问题。

为 QueryForm 新增属性

import { FormProps } from "antd/lib/form";

// 定义属性类型
interface Props extends FormProps {
  onDataChange(data: EmployeeResponse): void;
}
class QueryForm extends Component<Props, EmployeeRequest> {
  queryEmployee = (param: EmployeeRequest) => {
    get(GET_EMPLOYEE_URL, param).then((response) => {
      // 调用回调
      this.props.onDataChange(response.data);
    });
  };
}
复制代码

渲染成功

1.png

路由

为顶部菜单栏添加路由切换。

我们在 src 下添加 routers 文件夹,存放所有的路由配置。
将整个 App 定义为一个路由,用 <BrowserRouter> 包装。

/*
 ** src/routers/index.tsx
 */
import React from "react";
import { BrowserRouter, Route } from "react-router-dom";

import App from "../components/App";

const Root = () => (
  <BrowserRouter>
    <Route path="/*" component={App} />
  </BrowserRouter>
);

export default Root;
复制代码

将返回的 Root 渲染到首页中:

/*
 ** src/index.tsx
 */
import React from "react";
import ReactDOM from "react-dom";
import Root from "./routers";

ReactDOM.render(<Root />, document.querySelectorAll(".app")[0]);
复制代码

改造顶部菜单栏和路由匹配(新增/修改部分代码):

/*
 ** src/components/App.tsx
 */
import { Route, Link } from "react-router-dom";
const App = () => (
  <ConfigProvider locale={zhCN}>
    <Layout>
      <Header>
        <Menu>
          <Menu.Item key="employee">
            <Link to="/employee">员工管理</Link>
          </Menu.Item>
          <Menu.Item key="setting">
            <Link to="/setting">系统设置</Link>
          </Menu.Item>
        </Menu>
      </Header>
      <Content className="contentWrap">
        <div className="content">
          <Route path="/" exact component={Employee} />
          <Route path="/employee" component={Employee} />
          <Route path="/setting" component={Setting} />
        </div>
      </Content>
    </Layout>
  </ConfigProvider>
);
复制代码

菜单的默认值从路由中读取(match.url)(新增/修改部分代码):

/*
 ** src/components/App.tsx
 */
const App = ({ match }: any) => {
  let defaultKey = match.url.replace("/", "") || "employee";
  return ...;
};
复制代码

React & TS 系列

© 版权声明
THE END
喜欢就支持一下吧
点赞0 分享