我试图转换下面的类组件代码:
import React, { Component } from 'react'
import ReactTable from 'react-table'
import api from '../api'
import styled from 'styled-components'
import 'react-table/react-table.css'
const Wrapper = styled.div`
padding: 0 40px 40px 40px;
`
const Update = styled.div`
color: #ef9b0f;
cursor: pointer;
`
const Delete = styled.div`
color: #ff0000;
cursor: pointer;
`
class UpdateVoter extends Component {
updateUser = event => {
event.preventDefault()
window.location.href = `/voters/update/${this.props.id}`
}
render() {
return <Update onClick={this.updateUser}>Update</Update>
}
}
class DeleteVoter extends Component {
deleteUser = event => {
event.preventDefault()
if (
window.confirm(
`Do you want to delete this voter ${this.props.id} permanently?`,
)
) {
api.deleteVoterById(this.props.id)
window.location.reload()
}
}
render() {
return <Delete onClick={this.deleteUser}>Delete</Delete>
}
}
class VotersList extends Component {
constructor(props) {
super(props)
this.state = {
voters: [],
columns: [],
isLoading: false,
}
}
componentDidMount = async () => {
this.setState({ isLoading: true })
await api.getAllVoters().then(voters => {
this.setState({
voters: voters.data.data,
isLoading: false,
})
})
}
render() {
//const { voters, isLoading } = this.state
const columns = [
{
Header: 'ID',
accessor: '_id',
filterable: true,
},
{
Header: 'No KK',
accessor: 'nkk',
filterable: true,
},
{
Header: 'NIK',
accessor: 'nik',
filterable: true,
},
{
Header: 'Nama',
accessor: 'nama',
filterable: true,
},
{
Header: 'Alamat',
accessor: 'alamat',
filterable: true,
},
{
Header: '',
accessor: '',
Cell: function(props) {
return (
<span>
<DeleteVoter id={props.original._id} />
</span>
)
},
},
{
Header: '',
accessor: '',
Cell: function(props) {
return (
<span>
<UpdateVoter id={props.original._id} />
</span>
)
},
},
]
let showTable = true
if (!this.state.voters.length) {
showTable = false
}
return (
<Wrapper>
{showTable && (
<ReactTable
data={this.state.voters}
columns={columns}
loading={this.state.isLoading}
defaultPageSize={10}
showPageSizeOptions={true}
minRows={0}
/>
)}
</Wrapper>
)
}
}
export default VotersList
此功能组件代码:
import React, {useState, useEffect} from 'react'
import ReactTable from 'react-table'
import api from '../api'
import styled from 'styled-components'
import 'react-table/react-table.css'
const Wrapper = styled.div`
padding: 0 40px 40px 40px;
`
const Update = styled.div`
color: #ef9b0f;
cursor: pointer;
`
const Delete = styled.div`
color: #ff0000;
cursor: pointer;
`
function UpdateVoter(props) {
const updateUser = event => {
event.preventDefault()
window.location.href = `/voters/update/${props.id}`
}
return <Update onClick={updateUser}>Update</Update>
}
function DeleteVoter(props) {
const deleteUser = event => {
event.preventDefault()
if (
window.confirm(
`Do tou want to delete this voter ${props.id} permanently?`,
)
) {
api.deleteVoterById(props.id)
window.location.reload()
}
}
return <Delete onClick={deleteUser}>Delete</Delete>
}
function VotersList(props) {
const [voters, setVoters] = useState ({voters: []})
const [isLoading, setIsLoading] = useState ({isLoading: false})
useEffect(() => {
async function fetchData() {
setIsLoading(true)
return (setVoters(await api.getAllVoters()))
}
console.log(fetchData())
}, [])
const columns = [
{
Header: 'ID',
accessor: '_id',
},
{
Header: 'No KK',
accessor: 'nkk',
},
{
Header: 'NIK',
accessor: 'nik',
},
{
Header: 'Nama',
accessor: 'nama',
},
{
Header: 'Alamat',
accessor: 'alamat',
},
{
Header: '',
accessor: '',
Cell: function(props) {
return (
<span>
<DeleteVoter id={props.original._id} />
</span>
)
},
},
{
Header: '',
accessor: '',
Cell: function(props) {
return (
<span>
<UpdateVoter id={props.original._id} />
</span>
)
},
},
]
let showTable = true
if (!voters.length) {
showTable = false
}
return (
<Wrapper>
{showTable && (
<ReactTable
data={voters}
columns={columns}
loading={isLoading}
defaultPageSize={10}
showPageSizeOptions={true}
minRows={0}
/>
)}
</Wrapper>
)
}
export default VotersList
但是,我得到的结果是空白。该表未显示。我尝试在console.log(fetchData())
函数内进行useEffect
,并在控制台中打印了此结果Promise {<pending>}
。这是什么意思?为什么表格未按原样显示?预先非常感谢。
答案 0 :(得分:0)
您要从setVoter
中的fetchVoter
函数返回useEffect
,这就是控制台打印承诺的原因。
您应该尝试这样
async function fetchData() {
const data = await api.getAllVoters()
return data
}
async handleDataFetch() {
setIsLoading(true)
const data = await fetchData()
setVoters(data)
setIsLoading(false)
}
useEffect(() => {
handleDataFetch()
}, [])
答案 1 :(得分:0)
是什么意思?
Promise {<pending>}
告诉您该函数的结果是尚未解决的承诺。 An async
function will return a Promise when invoked without await
;
如果要查看网络请求的内容,则应在console.log
函数中fetchData
。
为什么表格未按原样显示?
我认为是因为您没有正确设置getAllVoters
结果。
在原始代码中,将API结果中的状态变量voters
设置为data.data
,而在重构后的代码中,您可以使用以下方法将其简单地设置为结果:
setVoters(await api.getAllVoters())
您可以将其更改为:
useEffect(() => {
async function fetchData() {
setIsLoading(true)
const voters = await api.getAllVoters();
setVoters(voters.data.data)
}
fetchData()
}, [])
值得一提的是您使用的useState
错误。
您正在这样使用它:
const [isLoading, setIsLoading] = useState({ isLoading: false });
它应该像这样使用:
const [isLoading, setIsLoading] = useState(false);
此刻,您正在将变量isLoading
设置为以下对象:{isLoading: false}
,而您只想将其设置为false。
当您立即使用setIsLoading(true)
将值更改为true时,这不会给您造成问题,但是,这很可能会导致错误。
useState ({voters: []})
也是如此。
答案 2 :(得分:0)
我相信您没有有效地使用useEffect
挂钩。我在您的代码中看到的问题很少,其中一个是将async
与一个函数配合使用(正确),但是async-await
的规则是当您拥有async
函数时无论您叫到哪里,都必须await
。
同样好的做法是将api逻辑放在useEffect
之外的单独函数中。
我在您的代码中发现的另一个问题是您的isLoading
状态被初始化为对象,但是在您的fetctData
函数中将其设置为bool值是错误的。您可以简单地将其初始化为true
并在获取数据后将其设置为false
因此,您上面VotersList
的组件代码将类似于以下内容
function VotersList(props) {
const [voters, setVoters] = useState({voters: []})
const [isLoading, setIsLoading] = useState(true)
const fetchData = async () => {
let allVoters = await api.getAllVoters();
setVoters(allVoters);
setIsLoading(false);
}
useEffect(async () => {
let allVoters = await api.getAllVoters();
setVoters(allVoters);
}, [])
// OR
/*
useEffect(async () => {
await fetchData();
}, [])
*/
const columns = [
{
Header: 'ID',
accessor: '_id',
},
{
Header: 'No KK',
accessor: 'nkk',
},
{
Header: 'NIK',
accessor: 'nik',
},
{
Header: 'Nama',
accessor: 'nama',
},
{
Header: 'Alamat',
accessor: 'alamat',
},
{
Header: '',
accessor: '',
Cell: function(props) {
return (
<span>
<DeleteVoter id={props.original._id} />
</span>
)
},
},
{
Header: '',
accessor: '',
Cell: function(props) {
return (
<span>
<UpdateVoter id={props.original._id} />
</span>
)
},
},
]
let showTable = true
if (!voters.length) {
showTable = false
}
return (
<Wrapper>
{showTable && (
<ReactTable
data={voters}
columns={columns}
loading={isLoading}
defaultPageSize={10}
showPageSizeOptions={true}
minRows={0}
/>
)}
</Wrapper>
)
}