V. Sambor
V. Sambor

Reputation: 13389

How to refactor react hooks nested function properly

I have a function component which uses two states and both are changed based on event triggered.

I've read on react docs that is a bad idea to change states in nested function or condition. I also seen some examples using useEffects, but I have no clear idea how to properly refactor this.

here is my entire component:

import React, { useState, useEffect } from 'react'
import './App.css'
import AppHeader from '../app-header'
import AppFooter from '../app-footer'
import SearchInput from '../search-input'
import Stats from '../stats'
import Chart from '../chart'
import { getBundleInfoAPI } from '../../services/hostApi'
import 'react-loader-spinner/dist/loader/css/react-spinner-loader.css'
import Loader from 'react-loader-spinner'

function App() {
  const [isSpinnerVisible, setSpinnerVisible] = useState(false)
  const [bundleData, setBundleData] = useState({})

  const _handleOnItemSelected = (item) => {
    if (item && item.package && item.package.name && item.package.version) {
      setSpinnerVisible(true)
      getBundleInfoAPI(item.package.name, item.package.version)
        .then(resposeData => setBundleData(resposeData))
        .finally(() => setSpinnerVisible(false))
    } else {
      // TODO - implement an error handler component?
      console.warn('WARNING: The selected bundle does not have name or version!')
    }
  }

  return (
    <div className="app">
      <AppHeader />

      <main>
        <SearchInput onItemSelected={_handleOnItemSelected} />

        <div className="app-main-inner-container">
          <Loader type="Triangle" color="#00BFFF" height={200} width={200} visible={isSpinnerVisible} />

          {!isSpinnerVisible &&
            <div className="app-stats-chart-container">
              <section className="app-stats-container"><Stats size={bundleData.stats} /></section>
              <section className="app-chart-container"><Chart bundleChartData={bundleData.chart} /></section>
            </div>
          }
        </div>
      </main>

      <AppFooter />
    </div>
  )
}

export default App

Upvotes: 0

Views: 215

Answers (2)

skyboyer
skyboyer

Reputation: 23705

Docs section you are referring to means you must not put line with useState inside of nested functions, conditions, loops.

Calling setter returned by hook is definitely fine and correct.

Upvotes: 2

user9035386
user9035386

Reputation:

This is fine, you are showing the loading screen when starting fetch and then hiding it when the fetch is done... no refactoring needed

Upvotes: 2

Related Questions