我正在参与掘金创作者训练营第6期,点击了解活动详情
目标
使用React.js库,结合ant-designUI组件库,实现一个表单添加,列表展示,支持搜索和分页的demo。
背景概况
React是用于构建用户界面的JavaScript库, 起源于Facebook的内部项目,于2013年5月开源。
React是什么
React 不是一个 MVC 框架。React 是一个用于构建可组合用户界面的库。 React主要用于构建UI。它鼓励创建那些用于呈现随时间变化数据的、可复用的 UI 组件。
特点
- 声明式设计:React 使创建交互式 UI 变得轻而易举。为你应用的每一个状态设计简洁的视图,当数据变动时 React能高效更新并渲染合适的组件。
- 组件化: 构建管理自身状态的封装组件,然后对其组合以构成复杂的 UI。
- 高效:React通过对DOM的模拟,最大限度地减少与DOM的交互。
- 灵活:无论你现在使用什么技术栈,在无需重写现有代码的前提下,通过引入React来开发新功能。
为什么使用React
- 使用组件化开发方式,符合现代Web开发的趋势。
- 技术成熟,社区完善,配件齐全,适用于大型Web项目(生态系统健全)。
- 由Facebook专门的团队维护,技术支持可靠。
- ReactNative - Learn once, write anywhere: Build mobile apps with React。
- 使用方式简单,性能非常高,支持服务端渲染。
- React非常火,从技术角度,可以满足好奇心,提高技术水平;从职业角度,有利于求职和晋升,有利于参与潜力大的项目。
基本使用
安装
安装node,参考之前的教程就好。戳这里
创建项目
创建新的 React 应用。产用官方推荐的 Create React App。 我在这里还搜集了其他创建项目的方法:如何从零开始创建React项目
Create React App
Create React App 全局安装 npm install -g create-react-app
以下三种选择其中的一种即可。我选择的yarn安装。
npx create-react-app my-app
npm init react-app my-app
yarn create react-app my-app
注意:
- 如果安装报错,有可能是npm源的问题。修改源即可。戳这里解决
- 安装完成之后,运行 yarn start。点击链接,出现如下界面,恭喜你,第一个React项目创建好了。
组件
React 组件可以让你把UI分割为独立、可复用的片段,并将每一片段视为相互独立的部分。 组件可以理解为,根据业务拆分出来,一块单独的功能模块。包括模板【html】、属性【props】和事件【通信】。
创建组件的两种方式 戳这里
-
函数组件(无状态组件)
-
function Welcome(props) { return <h1>Hello, {props.name}</h1>; } -
class组件(有状态组件)
-
class Welcome extends React.Component { render() { return <h1>Hello, {this.props.name}</h1>; } }
注意:
- 组件名称必须以大写字母开头。
- React 会将以小写字母开头的组件视为原生 DOM 标签。例如,
<div />代表 HTML 的 div 标签,而<Welcome />则代表一个组件,并且需在作用域内使用Welcome。 - 你可以在深入 JSX 中了解更多关于此规范的原因。
ant-design UI组件库
安装引入: 从 yarn 或 npm 安装并引入 antd。
yarn add antd
修改 src/App.css,在文件顶部引入 antd/dist/antd.css。
@import '~antd/dist/antd.css';
修改 src/App.js,引入 antd 的按钮组件。
import React from 'react';
import { Button } from 'antd';
import './App.css';
const App = () => (
<div className="App">
<Button type="primary">Button</Button>
</div>
);
export default App;
好了,现在你应该能看到页面上已经有了 antd 的蓝色按钮组件了。
JSX
注意:
- 在 JSX 中给元素添加类, 需要使用 className 代替 class。
- label 的 for属性,使用htmlFor代替。
- 在 JSX 中通过 {} 中间解析js代码。
- 在 JSX 中只能使用表达式,但是不能出现 语句。
- 在 JSX 中注释语法:{/* 中间是注释的内容 */}。
- JSx中,return,需要使用小括号包裹。
- 必须有返回值.return。
- 必须要有一个根节点。
<div>xxxx</div>
props 和 state
属性:props
组件之间传递数据。类似于Vue中的Props。 注意点: props只读,无法给props添加或修改属性。组件无论是使用函数声明还是通过 class 声明,都绝不能修改自身的 props。
状态:state
状态即数据
- 作用:提供模板渲染的数据。如果是和模板渲染无关的数据。
注意:
- 只有通过class创建的组件才具有状态
- 状态是私有的,完全由组件来控制
- 不要在 state 中添加 render() 方法中不需要的数据,会影响渲染性能!
- 正确地使用 State
组件通信
- 父组件-->子组件: props。
- 子组件-->父组件: props中的回调。
- 具体详细的组件通信请看这里
产出Demo
List.js
table展示数据。支持删除和编辑。
import React, { Component } from "react";
import { Button, Card, Divider, Table, Space, Popconfirm } from "antd";
import { uniqueId } from "lodash";
import Form from "./form";
export default class List extends Component {
constructor(props) {
super(props);
this.state = {
isOpen: false,
dataSource: [
{
key: "1",
name: "胡彦斌",
age: 32,
address: "西湖区湖底公园1号",
},
{
key: "2",
name: "胡彦祖",
age: 42,
address: "西湖区湖底公园1号",
},
],
};
this.columns = [
{
title: "姓名",
dataIndex: "name",
key: "name",
},
{
title: "年龄",
dataIndex: "age",
key: "age",
},
{
title: "住址",
dataIndex: "address",
key: "address",
},
{
title: "操作",
key: "action",
render: (_, record, index) => {
return (
<Space size="middle">
<Button type="primary">编辑</Button>
<Popconfirm
title="Sure to delete?"
onConfirm={() => this.handleDelete(record.key, index)}
>
<Button type="primary" danger>
删除
</Button>
</Popconfirm>
</Space>
);
},
},
];
}
handleDelete(rowKey, index) {
console.log(index, "===", this);
// const dataList = JSON.parse(JSON.stringify(this.state.dataSource));
// const newList = dataList.splice(index, 1);
// console.log(newList,dataList)
// this.setState({dataSource: dataList});
const newData = this.state.dataSource.filter((item) => item.key !== rowKey);
this.setState({ dataSource: newData });
}
handleAddForm() {
this.setState({ isOpen: true });
}
closeDialog(values) {
values.key = uniqueId("add_");
this.setState({
isOpen: false,
dataSource: [...this.state.dataSource, values],
});
}
render() {
return (
<div>
<Card hoverable={true}>
<Button type="primary" onClick={this.handleAddForm.bind(this)}>
{this.props.btnName}
</Button>
{/* this.props.btnName---> 接收App.js传递的参数 */}
</Card>
<Divider plain>分割线</Divider>
<Card hoverable={true}>
<Table
bordered
dataSource={this.state.dataSource}
columns={this.columns}
/>
</Card>
<Form
isOpen={this.state.isOpen}
closeDialog={(values) => this.closeDialog(values)}
></Form>
</div>
);
}
}
注意:
- state和setState。使用 setState() 方法修改状态,状态改变后,React会重新渲染组件。不要直接修改state属性的值,不会重新渲染组件。
- 组件绑定事件。 事件名称采用驼峰命名法。通过React事件机制 onClick 绑定。也可以通过ref操作dom绑定事件。戳这里。
- 事件绑定中的this。通过 bind 绑定和通过 箭头函数 绑定。
form.js
信息录入。写了函数组件和class组件。
函数组件
import React from "react";
import PropTypes from "prop-types";
import { Button, Modal, Form, Input, InputNumber } from "antd";
const { TextArea } = Input;
const FormData = (props) => {
const isModalVisible = props.isOpen;
const onFinish = (values) => {
props.closeDialog(values);
}
const newLocal = (
<Form
name="basic"
labelCol={{ span: 8 }}
wrapperCol={{ span: 16 }}
autoComplete="off"
initialValues={{
name: "张三",
age: 12,
address: "西湖区湖底公园1号",
}}
onFinish={(values) => onFinish(values)}
>
<Form.Item
label="姓名"
name="name"
rules={[{ required: true, message: "请输入名称" }]}
>
<Input />
</Form.Item>
<Form.Item
label="年龄"
name="age"
rules={[{ required: true, message: "请输入年龄" }]}
>
<InputNumber />
</Form.Item>
<Form.Item label="地址" name="address">
<TextArea rows={4} />
</Form.Item>
<Form.Item wrapperCol={{ offset: 8, span: 16 }}>
<Button type="primary" htmlType="submit">
创 建
</Button>
</Form.Item>
</Form>
);
return (
<div>
<Modal title="Basic Modal" visible={isModalVisible} footer={null}>
{newLocal}
</Modal>
</div>
);
};
FormData.propTypes = {
};
export default FormData;
class组件
import React, { Component } from "react";
import { Button, Modal, Checkbox, Form, Input, InputNumber } from "antd";
const { TextArea } = Input;
export default class FormData extends Component {
constructor(props) {
super(props);
}
onFinish(values) {
this.props.closeDialog(values);
}
render() {
const isModalVisible = this.props.isOpen;
const newLocal = <Form
name="basic"
labelCol={{ span: 8 }}
wrapperCol={{ span: 16 }}
autoComplete="off"
initialValues={{
name: "张三",
age: 12,
address: "西湖区湖底公园1号",
}}
onFinish={(values) => this.onFinish(values)}
>
<Form.Item
label="姓名"
name="name"
rules={[{ required: true, message: "请输入名称" }]}
>
<Input />
</Form.Item>
<Form.Item
label="年龄"
name="age"
rules={[{ required: true, message: "请输入年龄" }]}
>
<InputNumber />
</Form.Item>
<Form.Item label="地址" name="address">
<TextArea rows={4} />
</Form.Item>
<Form.Item wrapperCol={{ offset: 8, span: 16 }}>
<Button
type="primary"
htmlType="submit"
>
创 建
</Button>
</Form.Item>
</Form>;
return (
<div>
<Modal
title="Basic Modal"
visible={isModalVisible}
footer={null}
>
{newLocal}
</Modal>
</div>
);
}
}
总结
- 我们从零开始,构建了React项目,安装了ant-design搭配的UI框架,实现了列表展示、表单录入数据,可删除的功能。
- 初步学习了props,state和组件之间的通信。
- 这里也收集了比较优秀的文章React入门看这篇就够了;
- 推荐两个学习React,在vscode编辑器上比较友好的插件: React Component VSCode React Refactor