本文整合了 React 开发中的常用技巧,包括状态管理、路由和文件处理。

setState 处理嵌套数据

使用 Object.assign

1
2
3
this.setState({
foo: Object.assign({}, this.state.foo, { bar: 1 })
})

使用展开运算符(推荐)

1
2
3
4
5
6
this.setState({
foo: {
...this.state.foo,
bar: 1
}
})

使用 immer

1
2
3
4
5
6
7
import produce from 'immer'

this.setState(
produce(draft => {
draft.foo.bar = 1
})
)

React Router URL 参数

定义路由参数

1
<Route path="/user/:id" component={User} />

获取参数

1
2
3
4
5
6
7
8
9
10
// 函数组件
import { useParams } from 'react-router-dom'

function User() {
let { id } = useParams()
return <h1>User: {id}</h1>
}

// 类组件
this.props.match.params.id

多参数路由

1
<Route path="/user/:userId/post/:postId" component={Post} />

文件下载

使用 Blob 下载

1
2
3
4
5
6
7
8
9
10
11
function downloadFile(data, filename) {
const blob = new Blob([data], { type: 'text/csv' })
const url = window.URL.createObjectURL(blob)

const link = document.createElement('a')
link.href = url
link.setAttribute('download', filename)
document.body.appendChild(link)
link.click()
document.body.removeChild(link)
}

JSON 转 CSV 导出

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
function exportCSV(headers, items, filename) {
if (headers) {
items.unshift(headers)
}

const csv = items.map(row =>
Object.values(row).join(',')
).join('\n')

const blob = new Blob([csv], { type: 'text/csv;charset=utf-8;' })
const url = URL.createObjectURL(blob)

const link = document.createElement('a')
link.setAttribute('href', url)
link.setAttribute('download', filename + '.csv')
link.style.visibility = 'hidden'
document.body.appendChild(link)
link.click()
document.body.removeChild(link)
}

使用 react-csv

1
2
3
4
5
6
7
8
9
10
11
12
13
14
import { CSVDownload } from 'react-csv'

const CSVButton = ({ data, filename }) => {
if (data.length === 0) {
return <span>Loading...</span>
}
return (
<CSVDownload
target="_self"
filename={filename}
data={data}
/>
)
}

参考链接