← Back to home

The Latest Ref

The Latest Ref Pattern enables you to reference the most recent value of props, state, or callback without including it in the dependency array when using it inside a useEffect

example without the latest ref

const page = () => {
  const [selectedPetFood, setSelectedPetFood] = useState("food");
  const [selectedPet, setSelectedPet] = useState("dog");

  const handleClick = async () => {
    console.log(selectedPetFood, selectedPet, "before"); // {selectedPetFood: 'food', selectedPet: 'dog'}
    // changing the state of selectedPetFood to 'food1'
    await new Promise((resolve) => setTimeout(resolve, 3500));
    console.log(selectedPetFood, selectedPet, "after"); // {selectedPetFood: 'food', selectedPet: 'dog'}
  };
  return (
    <div className="w-96">
      <Input
        type="text"
        value={selectedPetFood}
        onChange={(e)=> setSelectedPetFood(e.target.value)}
      />
      <Input
        type="text"
        value={selectedPet}
        onChange={(e)=> setSelectedPet(e.target.value)}
      />
      <Button onClick={handleClick} disabled={!selectedPetFood || !selectedPet}>
        Submit
      </Button>
    </div>
  );
};

example with the latest ref

const page = () => {
  const [selectedPetFood, setSelectedPetFood] = useState("food");
  const [selectedPet, setSelectedPet] = useState("dog");
  const refSelectedPetFood = React.useRef(selectedPetFood);
  const refSelectedPet = React.useRef(selectedPet);

  React.useEffect(() => {
    refSelectedPetFood.current = selectedPetFood;
    refSelectedPet.current = selectedPet;
  }, [selectedPetFood, selectedPet]);
  const handleClick = async () => {
    console.log(refSelectedPetFood.current, refSelectedPet.current, "before"); // {selectedPetFood: 'food', selectedPet: 'dog'}
    // changing the state of selectedPetFood to 'food1'
    await new Promise((resolve) => setTimeout(resolve, 3500));
    console.log(refSelectedPetFood.current, refSelectedPet.current, "after");
  };
  return (
    <div className="w-96">
      <Input
        type="text"
        value={selectedPetFood}
        onChange={(e)=> setSelectedPetFood(e.target.value)}
      />
      <Input
        type="text"
        value={selectedPet}
        onChange={(e)=> setSelectedPet(e.target.value)}
      />
      <Button onClick={handleClick} disabled={!selectedPetFood || !selectedPet}>
        Submit
      </Button>
    </div>
  );
};