skip to Main Content

I’m building an app using React Native. I want to show information(text) under my CalendarList from the data I stored in an array. The array has the date as one of its props. I have a filtering function to filter the date based on the currentMonth. I updated the currentMonth every onMonthChange like this:

  onMonthChange={ async (month) => {
    setIsLoading(true)
    const monthInt = parseInt(month.dateString.split("-")[1])
    await setCurrentMonth(monthInt - 1)
  }}

This is my filtered data:

  const filteredData = async () => {
    const temp = datas.filter((item) => {
      const dateParts = item.dayOffDate.split("-")
      const month = Number(dateParts[1]) - 1
      return month === currentMonth
    })
    setFilteredData(temp)
    await setIsLoading(false)
  }

This is my View :

  <CalendarList/>
  {isLoading ? ( <ActivityIndicator size="small" />
  ) : (
    // this is the view that show the filtered data
    <FlatList
      data={filteredData}
      renderItem={renderListItem}
    />
  )}

I want it to show the loading indicator every time the filtered data updating, but it still not working…

I appreciate any help and questions, please ask if I have to explain it clearer. Thank you 🙂

2

Answers


  1. From the code you have given it looks like the loading indicator is not working as expected because the filteredData function is not actually called when the month changes. So try calling the filteredData function inside the onMonthChange handler and make sure it’s executed asynchronously.

    Updated onMonthChange would be:

    onMonthChange={ async (month) => {
      setIsLoading(true)
      const monthInt = parseInt(month.dateString.split("-")[1])
      await setCurrentMonth(monthInt - 1)
      await filteredData() // Call the filteredData function here
    }}
    

    Update the filteredData function like this:

    const filteredData = () => {
      const temp = datas.filter((item) => {
        const dateParts = item.dayOffDate.split("-")
        const month = Number(dateParts[1]) - 1
        return month === currentMonth
      })
      setFilteredData(temp)
      setIsLoading(false)
    }
    

    Now, when the month changes, setIsLoading(true) will be called, followed by the updating of currentMonth, and then the filteredData function will be called to update the filteredData state. Once that’s done, setIsLoading(false) will be called, and the loading indicator should disappear.

    Make sure that the initial value of isLoading is set to false. Also remember that you don’t need to use await when calling a setState function.

    Another issue can be the rendering of <CalendarList/> and isLoading being separate. So update the component like this:

    <>
      {isLoading ? ( <ActivityIndicator size="small" />
      ) : (
        // this is the view that show the filtered data
    <CalendarList/>
        <FlatList
          data={filteredData}
          renderItem={renderListItem}
        />
      )}
    </>
    
    Login or Signup to reply.
  2. You should be using useEffect‘s to track the month and filteredData changes.

    Something like this:

    const onMonthChange = month => {
      const monthInt = parseInt(month.dateString.split("-")[1])
      setCurrentMonth(monthInt - 1)
    }}
    
    const filteredData = () => {
      const temp = datas.filter((item) => {
        const dateParts = item.dayOffDate.split("-")
        const month = Number(dateParts[1]) - 1
        return month === currentMonth
      })
      setFilteredData(temp)
    }
    
    useEffect( _ => setIsLoading( true ), [ currentMonth ] )
    
    useEffect( _ => setIsLoading( false ), [ filteredData ] )
    
    return <>
      <ActivityIndicator size="small" animating={isLoading}/>
      <CalendarList onMonthChange={onMonthChange}/>
      <FlatList data={filteredData}/>
    </>
    

    Note the absence of async/await as it doesn’t work here.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search