Custom component

KoEunseo·2022년 8월 30일
0

코드스테이츠

목록 보기
29/45

modal

const Container
const ModalBtn
const Overlay
const ModalView
//1. Modal 컴포넌트 : 모달창이 열려있는지 닫혀있는지에 대한 상태.
//모달창은 처음에는 닫혀있어야하기때문에 초기값으로 false를 준다.
const Modal = () => {
  const [isOpen, setIsOpen] = useState(false);

//2. setIsOpen()을 사용해 isOpen의 상태를 변경한다.
//! 연산자를 사용해 이벤트가 발생할때마다 현재값과 반대값이 들어가도록 함
  const openModal = () => { setIsOpen(!isOpen) }

  return (
   <div>
      <Container>
        <ModalBtn
          onClick={openModal} //3. 클릭하면 이벤트 실행
          >
          //4. 삼항연산자로 조건부 렌더링. isOpen이 true면 전자, false면 후자가 실행되어 버튼 콘텐츠가 바뀐다.
          {isOpen ? "Opened" : "Open Modal"}
        </ModalBtn>
        {isOpen ?
          //3. true면 오버레이를 줌. 오버레이 클릭하면 모달창을 닫는다.
          <Overlay onclick={openModal}>
            <ModalView //이벤트버블링을 막기 위한 코드
              onClick={(e) => e.stopPropagation()}>
              <button //3. x클릭하면 모달창을 닫는다
                onClick={openModal}>x</button>
            </ModalView>
          </Overlay>
        }
        : null //아무것도 안뜸
      </Container>
   </div>
  )
}

더 생각해봐야 할 것

모달이 열린 상태에서 스크롤을 멈춰야 함.
시도해본것 1. 조건에 따라 클래스네임을 주기 2. useEffect
1은 전체 컨테이너(root)에 클래스네임을 줘야 기능할 것 같다.
2는 스크롤을 막긴 하는데 모달창이 안열려있어도 스크롤이 안되는 문제가 생김.

Toggle

const Container
const ToggleBody = styled.div`
  &.checked { 대충 체크됐을때 나타낼 css1}
`
const ToggleBtn = styled.div`
  &.checked { 대충 체크됐을때 나타낼 css2}
`
const Toggle = () => {
  //1. useState로 on/off상태 구현
  const [isOn, setIsOn] = useState(false);
  const toggleOn = () => {
    setIsOn(!isOn); //! 현재와 반대값 할당
  }
  
  return (
    <div>
      <Container>
        //클래스네임도 삼항연산자로 부여 가능
        <ToggleBody className={ isOn ? "checked" : "" } />
        <ToggleBtn className={ isOn ? "checked" : "" } />
      </Container>
    </div>
  )
}

Tab

const TabMenu
const Display
const Tab = () => {
  const [currentTab, setCurrentTab] = useState(0);
  const menuArr = [{name: 1, content: 1},{name: 2, content: 2},{name: 3, content: 3}]
  const selectMenu = (i) => { //index를 전달
  setCurrentTab(i)}
  
  return (
    <div>
      <TabMenu>
        {menuArr.map((el, i) => 
                     return (
                    <li
                      className={currentTab === i ? 'focus': ''
                      //index를 인자로 넘겨야하기때문에 화살표함수 형태로 작성한다. 함수실행하는 형태는xx
                      onClick={()=> selectMenu(i)}}
                      >{el.name}</li>))}
      </TabMenu>
      <Display>{menuArr[currentTab].content}</Display>
    </div>
  )
}

Tag

const Input
const Tag = () => {
  const initTags = ['javascript', 'react']
  const [tags, setTags] = useState(initTags)
  const removeTag = (i) => {
    setTags(tags.filter((el, index) => index !== i))
  }
  const addTag = (e) => {
    if(tags.includes(e.target.value) === false
      && e.target.valus === "") {
      setTags([...tags, e.target.value]);
  } else return "";
    //엔터치면 인풋 내 값을 초기화시킴
  const emptyValue = () => {
    ref.current.value = "";
  };
  return (
    <div>
      <Input>
        <ul>
          {tags.map((tag, i)=> (
            <li key={i}>
              <TagTitle>{tag}</TagTitle>
              <span //index를 넘기기 위해 익명함수 형태로 기재
                onClick={()=> {removeTag(i)}}>x</span>
            </li>
          ))}
        </ul>
        <input 
          onKeyUp={(e)=>{
            return e.key === 'Enter' ? 
              (
              addTags(e) //두가지 이벤트를 실행하려면 소괄호로 묶고 쉼표로 구분해준다.
              , emptyValue()): null
          }}
          />
      </Input>
    </div>
  )
}

useRef를 사용해서 태그가 있건 없건 엔터를 쳤을때 인풋창을 비우도록 해주었다. 이 비우는 걸 해주면 테스트는 통과하지 못하지만...ㅎ 여턴간 비워주는 게 유저경험에 좋을거라 생각함


Advenced

Autocomplete

ClickToEdit

profile
주니어 플러터 개발자의 고군분투기

0개의 댓글