useRef value not persisting

Viewed 78

I am building a weather app where i have an index page which displays a bunch of cards for each hour. I have a value (whether it is AM or PM) which i am storing in a useref and passing it to child component. When some condition is met an onChange function is called from the child (this function exist in the parent)and changes the value of the useref but the value is not changing in the child. The bunch of cards are displayed by mapping through them so i am expecting if the useref value is changed in the parent the next card would get the changed value but this is not happening. Am i using useref wrong? index.js

import type { NextPage } from 'next'
import WeatherCard from '../components/WeatherCard'
import { motion } from 'framer-motion'
import { useEffect, useRef, useState } from 'react'
import { PropsType } from '../types'

const Home: NextPage<PropsType> = (props) => {

  const [time,setTime]=useState(new Date());
  const timeFormatRef=React.useRef(new Date().toLocaleString('en-US', 
                    {hour: 'numeric', hour12: true }).split(' ')[1]) as any;
  
  const onTimeFormatChange=()=>{
    if(timeFormatRef.current==='AM')  
      timeFormatRef.current='PM' 
    else 
      timeFormatRef.current='AM';
  }
  
  return (
    <div className=>
      <main>
         {determineWeatherCardsArr().map((el,index)=>{
           return <motion.div>
                    <WeatherCard key={index} weather={el.weather} 
                                temp={el.temp} index={index} 
                                time={time} ref={timeFormatRef} 
                               onTimeFormatChange= {onTimeFormatChange}/>
                   </motion.div>})
      </main>
    </div>
  )
}

export default Home

WeatherCard.js

import Image from "next/image";

const WeatherCard:React.forwardref=(props,ref)=>{

    const determineHour=(time:Date):string=>{
        
        let amPmTimeArr=time.toLocaleString('en-US', 
                   { hour: 'numeric', hour12: true }).split(' ');
        let hour
        [hour]=[...amPmTimeArr]
        
        if(+hour+props.index>=12){
            hour=(+hour+props.index)%12;
        
            if(+hour===0){
               props.onTimeFormatChange();//changing the useref here 
               
            }
            
            return hour+ref.current;
        }
        else{
            hour=+hour+props.index
            return hour+ref.current;
        }
         
    }

    let cardTitle=determineHour(props.time)
    return(
        <div className="">
            <h3 className="">{cardTitle}</h3>
        </div>
    )
}

1 Answers

React does not 'react' to ref values changes so your child component will not be rerendered if the ref value changes. Use a state variable to achieve that

Related