ReasonJun

React: useState react one beat slower error 본문

Frontend/Error

React: useState react one beat slower error

ReasonJun 2023. 7. 31. 22:51
728x90

Problem : 

In the process of assigning the modified value in 'setTags' to the 'onChange' function, the value was updated one beat slowly.

code:

import React, { useState } from 'react';

interface ImageUploadProps {
  onChange: (value: string[]) => void;
  errors: any;
}

const TagInput: React.FC = ({ onChange, errors }) => {
  const [tags, setTags] = useState<string[]>([]);
  const [tag, setTag] = useState('');

  function removeTag(index: number) {
    setTags((prevTags) => prevTags.filter((_, i) => i !== index));
    onChange(tags);
  }

  function addTag() {
    let v = tag.trim();
    if (v === '') {
      return;
    }

    setTags([...tags, v]);
    onChange(tags);
    setTag('');
  }

  function manageKeyPress(e: React.KeyboardEvent) {
    if (e.key === 'Enter') {
      e.preventDefault();
      addTag();
    } else if (e.key === 'Backspace' && tag === '') {
      removeTag(tags.length - 1);
    }
  }
  

  return (
 

Why :

The issue with the onChange event being one step behind is due to the asynchronous nature of setState in React. When you call setState, the state update is not immediate, and the onChange function receives the old state.

To solve this issue, you can pass the updated tags array directly to the onChange function after it has been modified. Instead of using the tags state directly in the onChange function, use the updated prevTags value from the state updater function provided by useState.

 

Solution :

Here's the modified removeTag and addTag functions to address the issue:

// ... (other code remains the same)

function removeTag(index: number) {
  setTags((prevTags) => {
    const updatedTags = prevTags.filter((_, i) => i !== index);
    onChange(updatedTags);
    return updatedTags;
  });
}

function addTag() {
  let v = tag.trim();
  if (v === '') {
    return;
  }

  setTags((prevTags) => {
    const updatedTags = [...prevTags, v];
    onChange(updatedTags);
    return updatedTags;
  });
  setTag('');
}

With these changes, the onChange function will receive the updated tags array immediately after it is modified. The setTags functions now use the state updater functions, and the modified tags array is passed to the onChange function inside each updater function.

This should ensure that the onChange function receives the most up-to-date tags array when adding or removing tags in the TagInput component.

728x90
Comments