reactjs - React hooks 获取的数据不断链接到以前获取的数据
问题描述
我已经获取了一些持卡人数据并进行了渲染。当我单击一个按钮时,获取的数据只是添加到以前获取的数据中,而不是重新加载页面并呈现它们。下面是它的外观。单击按钮后,我需要重新渲染获取的数据,而不是继续添加。
*Button click and 5 cardholders renders
cardholder 1
cardholder 2
cardholder 3
cardholder 4
cardholder 5
*If I click the button again same 5 cardholders are added to above 5 cardholders instead of re-render the 5 cardholders
cardholder 1
cardholder 2
cardholder 3
cardholder 4
cardholder 5
cardholder 1
cardholder 2
cardholder 3
cardholder 4
cardholder 5
*父组件
function SecurityCenter () {
const [serverIp, setServerIp] = useState("")
const [port, setPort] = useState("")
const [username, setUsername] = useState("")
const [password, setPassword] = useState("")
const [fetchedData, setFetchedData] = useState([])
const handleSubmit = async (e) => {
e.preventDefault()
fetchData()
}
const fetchData = async () => {
try {
const response = await Api.post('/securityCenterApi/connection', {
serverIp: serverIp,
port: port,
username: username,
password: password
})
if (response.data.Rsp) {
const returnedData = response.data.Rsp.Result
setFetchedData(returnedData)
alert('Security Center Connected')
setServerIp("")
setPort("")
setUsername("")
setPassword("")
}
} catch (err) {
console.log(err)
alert('Please enter correct connection information')
}
}
return (
<>
<form onSubmit={handleSubmit}>
<div className='security-center-container'>
<p>Security Center</p>
<div className='server-ip'>
<p>Server IP:</p>
<div className="control">
<input className="input is-info" value={serverIp} onChange={e => setServerIp(e.currentTarget.value)} style={{width: '100%'}} type="text" placeholder="127.0.0.1"/>
</div>
</div>
<div className='port'>
<p>Port:</p>
<div className="control">
<input className="input is-info" value={port} onChange={e => setPort(e.currentTarget.value)} style={{width: '100%'}} type="text" placeholder="5000"/>
</div>
</div>
<div className='username'>
<p>Username</p>
<div className="control">
<input className="input is-info" value={username} onChange={e => setUsername(e.currentTarget.value)} style={{width: '100%'}} type="text" placeholder=""/>
</div>
</div>
<div className='password'>
<p>Password</p>
<div className="control">
<input className="input is-info" value={password} onChange={e => setPassword(e.currentTarget.value)} style={{width: '100%'}} type="text" placeholder=""/>
</div>
</div>
<div className='connect-button'>
<button className="button is-fullwidth is-link" style={{width: '100%'}}>Connect</button>
</div>
</div>
</form>
<div className="new-user-container">
</div>
<UserContainer
fetchedData={fetchedData}
setFetchedData={setFetchedData}
serverIp={serverIp}
setServerIp={setServerIp}
port={port}
setPort={setPort}
username={username}
setUsername={setUsername}
password={password}
setPassword={setPassword}
/>
</>
)
}
export default SecurityCenter
*子组件
function UserContainer (props) {
const [cardHolders, setCardHolders] = useState([])
useEffect(() => {
props.fetchedData.map(user => {
try {
const uuid = user.Guid
const response = Api.post(`/securityCenterApi/getCredentials/${uuid}`, {
serverIp: props.serverIp,
port: props.port,
username: props.username,
password: props.password
})
.then(response => {
const cardHolderCredentials = response.data.Rsp.Result.Credentials
const newGuid = Api.post(`/securityCenterApi/getUsers/${cardHolderCredentials}`, {
serverIp: props.serverIp,
port: props.port,
username: props.username,
password: props.password
})
.then(response => {
const userName = response.data.Rsp.Result.Cardholder.Name
const bitLength = response.data.Rsp.Result.Format.BitLength
const facilityCode = response.data.Rsp.Result.Format.Facility
const cardNumber = response.data.Rsp.Result.Format.CardId
setCardHolders(prev => [...prev, {
username: userName,
bitLength: bitLength,
facilityCode: facilityCode,
cardNumber: cardNumber
}])
}
)
})
} catch (err) {
console.log(err)
}
})
}, [props.fetchedData])
const renderCardHolders = () => {
return cardHolders.map((cardHolder, index) => {
return (
<tr key={index}>
<th>{cardHolder.username}</th>
<td>{cardHolder.bitLength}</td>
<td>{cardHolder.facilityCode}</td>
<td>{cardHolder.cardNumber}</td>
</tr>
)
})
}
return (
<table className="table">
<thead>
<tr>
<th><abbr title="name">Cardholder name</abbr></th>
<th><abbr title="wiegand">Wiegand Bit type</abbr></th>
<th><abbr title="facility">Facility Code</abbr></th>
<th><abbr title="card">Card number</abbr></th>
</tr>
</thead>
<tbody>
{renderCardHolders()}
</tbody>
</table>
)
}
export default UserContainer
先感谢您!
解决方案
我想到了。即使在渲染之后状态仍然存在,当我单击按钮重新获取持卡人时,没有任何信息被更改,这就是为什么它被连接到之前渲染的持卡人。我只是在我的 useEffect 挂钩中添加了一个简单的清理功能,以便在渲染后完成状态。
useEffect(() => {
props.fetchedData.map(user => {
try {
const uuid = user.Guid
const response = Api.post(`/securityCenterApi/getCredentials/${uuid}`, {
serverIp: props.serverIp,
port: props.port,
username: props.username,
password: props.password
})
.then(response => {
const cardHolderCredentials = response.data.Rsp.Result.Credentials
const newGuid = Api.post(`/securityCenterApi/getUsers/${cardHolderCredentials}`, {
serverIp: props.serverIp,
port: props.port,
username: props.username,
password: props.password
})
.then(response => {
console.log(response)
const userName = response.data.Rsp.Result.Cardholder.Name
const bitLength = response.data.Rsp.Result.Format.BitLength
const facilityCode = response.data.Rsp.Result.Format.Facility
const cardNumber = response.data.Rsp.Result.Format.CardId
setCardHolders(cardHolder => [...cardHolder, {
username: userName,
bitLength: bitLength,
facilityCode: facilityCode,
cardNumber: cardNumber
}])
}
)
})
} catch (err) {
console.log(err)
}
})
return () => {
setCardHolders([])
}
}, [props.fetchedData])
推荐阅读
- python - How do I fix syntax problems in my Python code
- google-maps - 父数据更新时,VueJS子组件GMAP不会重新渲染
- jquery - 在 TypeScript 中导入 jQuery 时,“无法调用类型缺少调用签名的表达式”
- android - 为什么我在 Kotlin 中使用委托时 isBackgroundWindow 返回错误?
- python - Pandas 数据框 - to_json() to_csv() 对于 iso 格式的日期的行为不同
- angular - 在角度元标记中显示特殊字符?
- postman - 邮递员:如何从响应中获取数字字符串值的计数
- python - Python/Stripe 发票创建未添加 line_item
- java - 为什么我不能创建内部类的实例?
- r - 从网络中获取加权矩阵