首页 > 解决方案 > 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

先感谢您!

标签: reactjsreact-hooks

解决方案


我想到了。即使在渲染之后状态仍然存在,当我单击按钮重新获取持卡人时,没有任何信息被更改,这就是为什么它被连接到之前渲染的持卡人。我只是在我的 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])

推荐阅读