728x90
구현하고자 하는 기능
회원약관에 있는 동의함 토글이 모두 동의함일때만 다음버튼 활성화
공통적으로 관리할 수 있는 useState의 경우는 하나로 관리
환경 : React Typescript MUI
전 코드
import React, { useState } from 'react';
import { Container, Radio, Box, RadioGroup, FormControlLabel, FormControl, Button, Typography, FormLabel } from '@mui/material';
import { useNavigate } from 'react-router-dom'; // useNavigate 훅 추가
// SignUpAgreeTerms 컴포넌트에 사용할 props 타입 정의
interface SignUpAgreeTermsProps {
handleNext: () => void;
handleBack: () => void;
}
export default function SignUpAgreeTerms({ handleNext, handleBack }: SignUpAgreeTermsProps) {
const navigate = useNavigate(); // useNavigate 훅 사용
const [termsAgree, setTermsAgree] = useState(false); // 이용약관 동의 여부 상태
const [privacyAgree, setPrivacyAgree] = useState(false); // 개인정보 수집 및 이용 동의 여부 상태
// 라디오 버튼 변경 핸들러
const handleRadioChange = (event: React.ChangeEvent<HTMLInputElement>) => {
const { name, value } = event.target;
if (name === 'terms-agree') {
setTermsAgree(value === 'true');
} else if (name === 'privacy-agree') {
setPrivacyAgree(value === 'true');
}
};
const handleBackToHome = () => {
navigate('/'); // 홈('/')으로 이동
};
return (
<React.Fragment>
{/* 이용약관 동의 */}
<>
<Typography sx={{ mt: 2, mb: 1 }} style={{ fontSize: '24px', fontWeight: 'bold' }}>
이용약관
</Typography>
<FormControl>
<Container sx={{ bgcolor: '#F8F8F8', height: 'auto', padding: '10px' }}>
제1조
<br />
이것은 관리자가 수정
<br />
제2조
이것은 관리자가 수정
</Container>
<RadioGroup
row
aria-labelledby="agree-terms-radio-group-label"
name="terms-agree" // 각각의 RadioGroup에 서로 다른 name 속성 사용
value={String(termsAgree)} // 현재 상태를 문자열로 변환하여 value로 설정
onChange={handleRadioChange} // 라디오 버튼의 변경 핸들러
>
{/* Radio 버튼들을 오른쪽 끝으로 정렬하기 위해 추가 */}
<Box sx={{ display: 'flex', justifyContent: 'flex-end', width: '100%' }}>
<FormControlLabel value="true" control={<Radio />} label="동의함" />
<FormControlLabel value="false" control={<Radio />} label="동의하지 않음" />
</Box>
</RadioGroup>
</FormControl>
</>
{/* 개인정보 수집 및 이용 동의 */}
<>
<Typography sx={{ mt: 2, mb: 1 }} style={{ fontSize: '24px', fontWeight: 'bold' }}>
개인정보 수집 및 이용 동의
</Typography>
<FormControl>
<Container sx={{ bgcolor: '#F8F8F8', height: 'auto', padding: '10px' }}>
<br />
<div style={{ fontWeight: 'bold' }}>수집하는 개인정보의 항목, 이용목적 및 보유기간</div>
</Container>
<RadioGroup
row
aria-labelledby="agree-privacy-radio-group-label"
name="privacy-agree" // 각각의 RadioGroup에 서로 다른 name 속성 사용
value={String(privacyAgree)} // 현재 상태를 문자열로 변환하여 value로 설정
onChange={handleRadioChange} // 라디오 버튼의 변경 핸들러
>
{/* Radio 버튼들을 오른쪽 끝으로 정렬하기 위해 추가 */}
<Box sx={{ display: 'flex', justifyContent: 'flex-end', width: '100%' }}>
<FormControlLabel value="true" control={<Radio />} label="동의함" />
<FormControlLabel value="false" control={<Radio />} label="동의하지 않음" />
</Box>
</RadioGroup>
</FormControl>
</>
{/* 이전 및 다음 버튼 */}
<Box sx={{ display: 'flex', flexDirection: 'row', pt: 2 }}>
<Button color="inherit" onClick={handleBackToHome} sx={{ mr: 1 }}>
이전
</Button>
<Box sx={{ flex: '1 1 auto' }} />
<Button onClick={handleNext}>다음</Button>
</Box>
</React.Fragment>
);
}
후코드
import React, { useState } from 'react';
import { Container, Radio, Box, RadioGroup, FormControlLabel, FormControl, Button, Typography } from '@mui/material';
import { useNavigate } from 'react-router-dom'; // useNavigate 훅 추가
interface SignUpAgreeTermsProps {
handleNext: () => void;
handleBack: () => void;
}
export default function SignUpAgreeTerms({ handleNext, handleBack }: SignUpAgreeTermsProps) {
const navigate = useNavigate(); // useNavigate 훅 사용
// 동의 상태를 배열로 관리 (index 0: termsAgree, index 1: privacyAgree)
const [agreements, setAgreements] = useState([false, false]);
// 라디오 버튼 변경 핸들러
const handleRadioChange = (event: React.ChangeEvent<HTMLInputElement>) => {
const { name, value } = event.target;
const newAgreements = [...agreements]; // 상태 배열 복사
if (name === 'terms-agree') {
newAgreements[0] = value === 'true'; // 이용약관 동의 여부 업데이트
} else if (name === 'privacy-agree') {
newAgreements[1] = value === 'true'; // 개인정보 동의 여부 업데이트
}
setAgreements(newAgreements); // 상태 업데이트
};
const handleBackToHome = () => {
navigate('/'); // 홈('/')으로 이동
};
return (
<React.Fragment>
{/* 이용약관 동의 */}
<>
<Typography sx={{ mt: 2, mb: 1 }} style={{ fontSize: '24px', fontWeight: 'bold' }}>
이용약관
</Typography>
<FormControl>
<Container sx={{ bgcolor: '#F8F8F8', height: 'auto', padding: '10px' }}>
제1조
<br />
이것은 관리자가 수정
<br />
제2조
이것은 관리자가 수정
</Container>
<RadioGroup
row
aria-labelledby="agree-terms-radio-group-label"
name="terms-agree" // 각각의 RadioGroup에 서로 다른 name 속성 사용
value={String(agreements[0])} // 현재 상태를 문자열로 변환하여 value로 설정
onChange={handleRadioChange} // 라디오 버튼의 변경 핸들러
>
<Box sx={{ display: 'flex', justifyContent: 'flex-end', width: '100%' }}>
<FormControlLabel value="true" control={<Radio />} label="동의함" />
<FormControlLabel value="false" control={<Radio />} label="동의하지 않음" />
</Box>
</RadioGroup>
</FormControl>
</>
{/* 개인정보 수집 및 이용 동의 */}
<>
<Typography sx={{ mt: 2, mb: 1 }} style={{ fontSize: '24px', fontWeight: 'bold' }}>
개인정보 수집 및 이용 동의
</Typography>
<FormControl>
<Container sx={{ bgcolor: '#F8F8F8', height: 'auto', padding: '10px' }}>
<br />
<br />
<div style={{ fontWeight: 'bold' }}>수집하는 개인정보의 항목, 이용목적 및 보유기간</div>
</Container>
<RadioGroup
row
aria-labelledby="agree-privacy-radio-group-label"
name="privacy-agree" // 각각의 RadioGroup에 서로 다른 name 속성 사용
value={String(agreements[1])} // 현재 상태를 문자열로 변환하여 value로 설정
onChange={handleRadioChange} // 라디오 버튼의 변경 핸들러
>
<Box sx={{ display: 'flex', justifyContent: 'flex-end', width: '100%' }}>
<FormControlLabel value="true" control={<Radio />} label="동의함" />
<FormControlLabel value="false" control={<Radio />} label="동의하지 않음" />
</Box>
</RadioGroup>
</FormControl>
</>
{/* 이전 및 다음 버튼 */}
<Box sx={{ display: 'flex', flexDirection: 'row', pt: 2 }}>
<Button color="inherit" onClick={handleBackToHome} sx={{ mr: 1 }}>
이전
</Button>
<Box sx={{ flex: '1 1 auto' }} />
{/* 두개의 동의가 모두 true일 때만 버튼 활성화 */}
<Button onClick={handleNext} disabled={!agreements[0] || !agreements[1]}>
다음
</Button>
</Box>
</React.Fragment>
);
}
'2. FrontEnd > React' 카테고리의 다른 글
[ MUI ] @toolpad/core의 Account slots menuItems 적용 안되는 문제 (0) | 2024.10.10 |
---|---|
[ React ] 로그인 안될경우, 로그인 페이지로 리다이렉트 (+예외처리) (0) | 2024.10.02 |
[ React ] 이메일 유효성 검사 후 에러메세지 띄우는 로직 (onBlur 이벤트) (0) | 2024.09.20 |
[React] AuthContext를 사용하여 로그인 관리하기 (1) | 2024.06.11 |
[React] CRA(create-react-app) + TypeScript 세팅 +.eslintrc +.prettierrc (0) | 2024.06.10 |