安装React框架以及相关库
安装相关库
安装react工具
1
| npm install g react-create-app
|
工程初始化
采用TypeScript开发
使用react工具创建TS模板工程
1
| npx create-react-app xxx --template typescript
|
引入UI库 Ant
引入现成的UI库 Ant 减少工作量
Ant组件使用
文件上传输入框
采用Ant现成的组件Dragger
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34
| render(): React.ReactNode { return <div style={{ 'marginLeft': "5%", "marginRight": "5%" }}> <Dragger name='file' multiple={true} action={API.upload} headers={{ "Access-Control-Allow-Origin": "*" }} onChange={(info) => { const { status } = info.file; console.log("onChange", info) if (status !== 'uploading') { console.log(info.file, info.fileList); } if (status === 'done') { message.success(`${info.file.name} file uploaded successfully.`); Actions.UpdateFileList(this.props.updateFileList) } else if (status === 'error') { message.error(`${info.file.name} file upload failed.`); } }} onDrop={(e) => { console.log('Dropped files', e.dataTransfer.files); }} > <p className="ant-upload-drag-icon"> <InboxOutlined /> </p> <p className="ant-upload-text">点击或将文件拖动到此处进行上传</p> <p className="ant-upload-hint"> 支持单次或批量上传 </p> </Dragger> </div > }
|
文件列表
采用Ant现成的组件List
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| render(): React.ReactNode { return <div style={{ 'marginLeft': "5%", "marginRight": "5%" }}> <List className='MyList' itemLayout='vertical' size='default' split={true} dataSource={this.props.data} pagination={this.getPaginationConfig()} renderItem={this.renderItem.bind(this)} > </List> </div> }
|
文件页面需要从server拉取文件列表以刷新界面,考虑到会动态刷界面,引入Redux框架管理数据
1 2 3
| npm install redux npm install react-redux npm install @reduxjs/toolkit
|
- 注意:新版Redux框架的Reducer使用方式可以参考toolkit库
Redux使用示例
Action 生成
Action 类似发起的一个事件,由Reducer接受,并接受Aciton携带的数据。将收到的数据更新进store根数据中,此时使用对应数据的界面也会随之刷新。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
|
static UpdateFileList(dispatch: Function) { API.json(API.fileList, (result: any, error: any) => { if (error != null) { console.log("UpdateFileList Error:", error) return } if (!(result instanceof Array)) { console.log("UpdateFileList Error:", result) return } dispatch(result) }) }
|
Action 发起与使用,和dispatch方法的使用,都需要先在组件中绑定
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
|
const mapStateToProps = (state: any) => { return { data: state.fileList.items, }; };
const mapDispatchToProps = (dispatch: any) => { return { updateFileList: (data: any) => dispatch(update(data)) }; };
export default connect(mapStateToProps, mapDispatchToProps)(FileList)
|
List组件加载完成后,发起Action事件,从服务器拉文件列表
1 2 3
| componentDidMount() { Actions.UpdateFileList(this.props.updateFileList) }
|
Reducer 接受数据
借助toolkit中的方法快速生成一个reducer
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26
|
export const FileListSlice = createSlice({ name: "fileList", initialState: { items: [], }, reducers: { update: (state, action) => { action.payload.sort((a: FileItem, b: FileItem) => { let ta = new Date(a.update) let tb = new Date(b.update) return tb.getTime() - ta.getTime() }) state.items = action.payload }, } })
export const { update, } = FileListSlice.actions
export default FileListSlice.reducer
|
store 主数据
每个react工程,仅有一个store数据结构
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| export const store = configureStore({ reducer: { fileList: FileListSlice, } })
function App() { return ( <Provider store={store}> <div className="App"> <FilePage></FilePage> </div> </Provider> ); }
|
文件的上传与下载
文件上传
文件上传工程由Ant自带的Dragger组件实现,设置正确的上传地址即可
1 2 3 4 5 6 7 8 9 10 11
| render(): React.ReactNode { return <Dragger // ...... action={API.upload} // ...... > { // ...... } </Dragger> }
|
文件下载
文件下载借助html的 标签即可
1 2 3 4 5 6 7 8 9 10 11 12 13 14
|
static DownloadFile(data: any, callback: Function) { const fileName = data.name; const linkNode = document.createElement('a'); linkNode.download = fileName; linkNode.style.display = 'none'; linkNode.href = `${API.download}?md5=${data.md5}` document.body.appendChild(linkNode); linkNode.click(); URL.revokeObjectURL(linkNode.href); document.body.removeChild(linkNode); }
|
发布工程