Home > Net >  data rendering issue after button is clicked in react
data rendering issue after button is clicked in react

Time:03-29

I am having a data rendering issue in react. Somehow, data is not automatically updated after it's updated in the server side. I can't put all the code in here, cuz the code is kind of lengthy. so i pasted/renamed some variables. Even if some variables are missing, please understand. Basically, I have a button on the page and when the button is clicked, the status changes to 'UPLOADING' and the function checkIfDataExists is called to fetch data from the server side and data should be automatically updated without page refresh, but when I test this, data is successfully retrieved from the server side, but the updated data is not rendered. I see 'successful...' on the Console. Is there anything wrong?

const Settings: React.FC<IProps> = props => {
  const { orgId } = props
  const password = 'dummy'
  const { data } = httpCall(`/${orgId}/${userId}/settings`)

  return (
    <div>
      {data && <SettingsForm data={data} password={password} {...props} />}
    </div>
  )
}

const SettingsForm: React.FC<Settings & IProps> = ({
  data,
  password
}) => {
  const [status, setStatus] = useState<'ERROR' | 'DONE' | 'UPLOADING'>()
  const service = getServiceInstance(data.organizationId)

  function checkIfDataExists(user: any) {
    return () => {
      httpCall
        .getClient(user.id)
        .then(value => {
          console.log('successful...')
          data.modeUsername = value.modeUsername
          data.modePassword = value.modePassword
        })
        .catch(() => {
          setStatus('ERROR')
        })
    }
  }
  useEffect(() => {
    if (!status) return
   switch (status) {
     case 'UPLOADING': {
       const timer = setInterval(
         checkIfDataExists({ id: data.id }),
         2000
       )
       return () => clearInterval(timer)
     }
   }
 }, [status, client
])

<div className="info-section">
    <p className="detail">Username</p>
    <p>{data.modeUsername}</p>
</div>
<div className="info-section">
    <p className="detail">Password</p>
    <p>{data.modePassword}</p>
</div>

CodePudding user response:

The problem I see is that after you setInterval an API you didn't set in the state to trigger the component to rerender. You don't need to be explicit to define resData to data because if you define data already useState already it types.

const SettingsForm: React.FC<Settings & IProps> = ({
  data,
  password
}) => {
  const [resdata,setResData] = useState(data)
  const [status, setStatus] = useState<'ERROR' | 'DONE' | 'UPLOADING'>()
  const service = getServiceInstance(data.organizationId)

  function checkIfDataExists(user: any) {
    return () => {
      httpCall
        .getClient(user.id)
        .then(value => {
          console.log('successful...')
          setResData({
             modeUsername: value.modeUsername,
             modePassword: value.modePassword,
          })
          // data.modeUsername = value.modeUsername
          // data.modePassword = value.modePassword
        })
        .catch(() => {
          setStatus('ERROR')
        })
    }
  }
  useEffect(() => {
    if (!status) return
   switch (status) {
     case 'UPLOADING': {
       const timer = setInterval(
         checkIfDataExists({ id: data.id }),
         2000
       )
       return () => clearInterval(timer)
     }
   }
 }, [status, client
])

<div className="info-section">
    <p className="detail">Username</p>
    <p>{resdata.modeUsername}</p>
</div>
<div className="info-section">
    <p className="detail">Password</p>
    <p>{resdata.modePassword}</p>
</div>
  • Related