button disabled

PromptAction·2024년 8월 29일
0

프론트엔드

목록 보기
16/16

button 태그의 속성중에 disabled라고 있다.

이게 뭐냐

말 그대로 버튼을 비활성화 시키는 것이다. 버튼을 비활성화 하여 사용자가 클릭하거나 상호작용 할 수 없도록 설정하는 속성이다.

기본 사용법

<button disabled>버튼</button>

-> disabled 속성이 추가되면 버튼이 회색으로 표시되며 사용자가 클릭할 수 없게 된다.

마우스 커서가 저 버튼 위에 있어도 커서 모양이 바뀌지 않는다.

비활성화 된 버튼은 폼 제출 시 서버로 전송되지 않는다. 즉 form 안에 있는 disabled 버튼은 제출되지 않는다.

이걸 동적으로 변경할 수도 있다

const button = document.querySelector('button');

// 버튼 비활성화
button.disabled = true;

// 버튼 활성화
button.disabled = false;

이 버튼에 css 스타일링을 추가할 수도 있다.

button:disabled {
    background-color: lightgray;
    color: darkgray;
    cursor: not-allowed;
}

뭐 이런식으로 넣어주면 볼만해진다.

그럼 얘를 좀 응용해서 어디다 쓰냐?

데이터 요청 중에 버튼을 비활성화 하여 사용자가 짧은 시간 안에 두번 이상, 중복 클릭하거나 불필요한 요청을 보내지 않도록 하는데에 쓰인다.

이걸 React Query의 isLoading과 연관지어서 써보자.

  • useQuery의 상태를 사용해 요청이 진행 중일 때는 버튼을 비활성화 한다. isLoading이나 isFetching, isRefetching, useMutation의 isPending과 함께 써보자

예시 )

import { useQuery } from 'react-query';

function MyComponent() {
    const { data, isLoading, refetch } = useQuery('fetchData', fetchDataFunction);

    return (
        <div>
            <button onClick={refetch} disabled={isLoading}>
                {isLoading ? '로딩 중...' : '데이터 새로 고침'}
            </button>
            {data && <div>{JSON.stringify(data)}</div>}
        </div>
    );
}

사용자가 버튼을 클릭하면 refetch가 호출되고 데이터 갱신을 위해 다시 요청한다.

isLoading일 때 ( isLoading은 첫 요청(마운트)) 때 . isLoading이 true 일 때 -> 즉 로딩 중일 때 버튼이 비활성화 된다. 이로 인해 사용자는 데이터가 로드되는 동안 추가 클릭을 하지 못하게 된다.

이 때 로딩중.. 과 비슷한 문구를 넣어주면 의미가 정확히 전달될 것이다.

나는 이런식으로 썼다

const { refetch } = useQuery({
        queryKey: ['token'],
        queryFn: async () => {
            const response = await axios.get('/api/token-verify', {
                withCredentials: true,
            })
            return response.data
        },
    })

    const router = useRouter()
    const employeeLogin = useMutation({
        mutationFn: async (data: IEmployeeLoginData) => {
            const tokenData = await axios.post('/api/employee-login', data)

            return setToken(tokenData.data.token)
        },
        onSuccess: async () => {
            await refetch()
            toast.success('로그인 성공')
            router.push('/')
        },
        onError: (error: any) => {
            toast.error(error.response.data.message)
        },
    })
    
    
    <button  disabled={employeeLogin.isPending}
             className="bg-white text-blue-600 border-blue-600 border-2 border-solid rounded-md h-12 p-3 mt-6 hover:bg-[#0A74B9] hover:text-white transition duration-300 w-full">
  {employeeLogin.isPending ? (<div className="flex items-center justify-center"> <div className="animate-spin rounded-full h-5 w-5 border-b-2 border-white"></div> </div> ) : ('로그인')} </button>

물론 로그인이 되면 다음 페이지로 넘어가겠지만, 다시 요청을 보내 성능을 떨어뜨리거나 불필요한 요청을 또 보내지 않고 사용자의 경험을 향상시키고, 상태 관리를 편하게 하기 위해 사용했다.

저기 조건부 안의

<div className="animate-spin rounded-full h-5 w-5 border-b-2 border-white"></div>

원이 돌아가는 표시인데 맘에 들게 만들어진것같아서 자주 쓴다.

하여튼 React Query의 refetch, isLoading, isFetching, isPending 과 함께 써주면 좋은 button의 disabled 속성에 대해 알아보았다.

0개의 댓글