리액트로 라디오 버튼을 만들어보자!
만들 예제의 완성본
- 버튼이나 텍스트를 클릭하면 버튼이 파란색으로 바뀐다.
- 버튼을 hover 하면 버튼 테두리가 회색으로 바뀐다.
Radio 컴포넌트 만들기
Radio 컴포넌트는 개별 라디오 버튼을 나타낸다.
라디오 버튼은 HTML에서 <input> 요소의 type 속성을 radio로 설정해주면 얻을 수 있다.
라디오 버튼은 여러 개의 선택 사항 중에 사용자로 부터 하나를 선택받기 위해서 사용된다.
텍스트를 클릭햇을 때도 라디오 버튼이 선택될 수 있도록 하려면,
<label> 요소로 <input> 요소와 children prop 모두 감싸주면 된다.
Radio.jsx
import "./Radio.css";
export const Radio = ({ children, value, name, defaultChecked, disabled }) => (
<label>
<input
type="radio"
value={value}
name={name}
defaultChecked={defaultChecked}
disabled={disabled}
className="gender-input"
/>
{children}
</label>
);
Radio 컴포넌트 스타일링하기
Radio.css
.gender-input {
margin-right: 16px;
}
[type="radio"] {
vertical-align: middle;
appearance: none;
border: max(2px, 0.1em) solid gray;
border-radius: 50%;
width: 1.25em;
height: 1.25em;
}
[type="radio"]:checked {
border: 0.4em solid blue;
}
[type="radio"]:focus-visible {
outline: max(2px, 0.1em) dotted blue;
outline-offset: max(2px, 0.1em);
}
[type="radio"]:hover {
box-shadow: 0 0 0 max(4px, 0.2em) lightgray;
cursor: pointer;
}
[type="radio"]:hover + span {
cursor: pointer;
}
[type="radio"]:disabled {
background-color: lightgray;
box-shadow: none;
opacity: 0.7;
cursor: not-allowed;
}
[type="radio"]:disabled + span {
opacity: 0.7;
cursor: not-allowed;
}
RadioGroup 컴포넌트 만들기
RadioGroup 컴포넌트는 여러 개의 라디오 버튼을 담을 수 있게 한다.
라디오 버튼은 항상 그룹을 지어 사용되는 경우가 대부분이기 때문이다.
(ex. 여기서의 신고 모달창 예시와 다른 경우에, 라디오 버튼은 주로 2개씩 그룹지어 사용된다. (ex. 남/녀, 이메일/SMS 등등)
label prop으로 해당 라디오 그룹의 목적을 텍스트로 받아서 HTML의 <legend> 요소를 이용하여 표시해준다.
그리고 HTML의 <fieldset> 요소를 이용하여 children prop으로 넘어온 여러 개의 라디오 버튼을 묶어준다.
RadioGroup.jsx
export const RadioGroup = ({ label, children }) => (
<fieldset className="radio-container">
<legend>{label}</legend>
{children}
</fieldset>
);
ReportModal 컴포넌트 마크업하기
<Radio /> 와 <RadioModal />을 import 해서 마크업하고, 스타일링까지 하면 완성이다.
ReportModal.jsx
import { Radio } from "./Radio";
import { RadioGroup } from "./RadioGroup";
import "./ReportModal.css";
const ReportModal = () => {
return (
<>
<div className="report-modal-container">
<label className="report-modal-select" htmlFor="report-reason">
<div className="report-modal-title">신고 사유를 선택해주세요</div>
</label>
<form className="report-modal-radio-container">
<RadioGroup>
<Radio
name="report-reason"
value="INAPPROPRIATE-SUBJECT"
defaultChecked
>
부적절한 주제
</Radio>
<Radio name="report-reason" value="INACCURATE-IMFORMAION">
부정확한 정보
</Radio>
<Radio name="report-reason" value="DUPLICATION">
중복 게시물 도배
</Radio>
<Radio name="report-reason" value="UNRELATED-SUBJECT">
주제와 맞지 않음
</Radio>
<Radio name="report-reason" value="SWEAR">
욕설 및 비방
</Radio>
<Radio name="report-reason" value="ETC">
기타
<input
className="report-modal-etc-input"
type="text"
id="etc"
maxLength={50}
></input>
</Radio>
</RadioGroup>
</form>
<div className="report-btn-container">
<button type="submit" className="report-btn">
신고하기
</button>
</div>
</div>
</>
);
};
export default ReportModal;
완성본 영상
참고 자료
https://www.daleseo.com/react-radio-buttons/
https://www.daleseo.com/css-html-radio/
'Libraries > React' 카테고리의 다른 글
[React] children 정말 쉽게 이해하기 (1) | 2024.12.09 |
---|---|
[React] KAKAO(카카오) 지도 API 사용법, 웹에 카카오맵 불러오는 법 (26) | 2024.10.15 |
[React] 리액트로 서버에 데이터 요청하는 방법 (fetch, axios.then, async/await 사용하기) (0) | 2024.08.30 |
[React] 스크롤 top 버튼 기능 구현하기 (0) | 2024.01.07 |
[React] 작성 날짜 기준으로 지난 시간을 변환하기 (리뷰시간, 게시글 시간, 댓글시간, 방금전, 몇분전, 몇시간전, 며칠전) (2) | 2024.01.06 |