드로잉윗유를 개발하면서 styled-components를 사용하고 있습니다.
그런데 input onChange()가 일어나면 focus가 아웃되는 상황이 생겨 해결 방법을 기록합니다.
컴포넌트 구조
현재 저의 프로젝트는 atom design패턴을 적용하여 컴포넌트를 개발하고 있습니다.
Atom -> button, Input
Molecule -> FormInputGroup
Organism -> NewRoomModal
의 구조로 되어있습니다.
//Modal.jsx
import styled from "styled-components";
import Icons from "@/components/Atom/Icons/Icons.jsx";
const Modal = ({children,clickClose}) => {
return (
<Overlay>
<Card>
<CloseBox onClick={clickClose}>
<Icons name={'closeIcon'}></Icons>
</CloseBox>
{children}
</Card>
</Overlay>
)
}
export default Modal
const Overlay = styled.div`
background: rgba(0,0,0, .2);
position: fixed;
top:0;
left: 0;
height: 100%;
width: 100%;
`
const Card = styled.div`
width: fit-content;
height: fit-content;
background: #FFF;
position: absolute;
top: 0;
left: 50%;
transform: translate(-50%, 75px);
border-radius: 10px;
padding: 10px;
display: flex;
flex-direction: column;
`
const CloseBox = styled.div`
width: fit-content;
align-self: end;
cursor: pointer;
`
//NewRoomModal.jsx
import Modal from "@/components/Molecule/Modal/Modal.jsx";
import FormInputGroup from "@/components/Molecule/FormInputGroup/FormInputGroup.jsx";
import styled from "styled-components";
import useForm from "@/hooks/useForm.jsx";
import {socket} from "@/server.jsx";
import {useNavigate} from "react-router-dom";
const NewRoomModal = ({isNewRoom,clickClose}) => {
const navigate = useNavigate();
const{ values, handleChange, handleSubmit } = useForm({
initValues:{
roomName :''
},
onSubmit: () => {
socket.emit('create-room',values,()=>{
navigate(`/room/${values.roomName}`)
});
}
})
const Children = () =>{
return (
<FormInputGroup btnInner='생성' inputName='roomName' onSubmit={handleSubmit} onChange={handleChange}/>
}
return (
<>
{isNewRoom && <Modal children={Children} >
}
</>
)
}
export default NewRoomModal
오류 발생
react는 state 값이 변경 될 때마다 매번 컴포넌트의 리렌더링이 발생합니다.
onChange가 일어나면 children이 리렌더링 되기 때문에 input focus를 잃어버리게 되었습니다.
해결 방법
import Modal from "@/components/Molecule/Modal/Modal.jsx";
import FormInputGroup from "@/components/Molecule/FormInputGroup/FormInputGroup.jsx";
import styled from "styled-components";
import useForm from "@/hooks/useForm.jsx";
import {socket} from "@/server.jsx";
import {useNavigate} from "react-router-dom";
const NewRoomModal = ({isNewRoom,clickClose}) => {
const navigate = useNavigate();
const{ values, handleChange, handleSubmit } = useForm({
initValues:{
roomName :''
},
onSubmit: () => {
socket.emit('create-room',values,()=>{
navigate(`/room/${values.roomName}`)
});
}
})
return (
<>
{isNewRoom &&
<ModalStyle clickClose={clickClose}>
<FormInputGroup btnInner='생성' name='roomName' onSubmit={handleSubmit} onChange={handleChange}/>
</ModalStyle>
}
</>
)
}
export default NewRoomModal
const ModalStyle = styled(Modal)`
`
return하지 않고 HTML Body로 넣어줘서 해결하였습니다.
혹시 저와같은 문제가 아닌 분들은 styled-component의 위치를 확인해 보시고 컴포넌트 안에 선언 되어있으면 컴포넌트 밖에 선언해주시면 됩니다!!
'React' 카테고리의 다른 글
[React] 페이지 이동시 스크롤 상단으로 (2) | 2022.11.03 |
---|---|
[React] 중첩 라우팅 설정후 URL이 변경 되었음에도 페이지에 나타나지 않을때 (0) | 2022.10.31 |