Skip to content

Week2 FrontEnd

김정훈 edited this page Aug 14, 2023 · 1 revision
  • Week 2

문제 상황

Gridient 영역에서 스크롤이 되지 않음

  • 원인: gradient 영역의 z-index 의 값이 가장 높아서 gradient영역에서 마우스로 스크롤 했을 때, z-index값이 낮은 요소의 스크롤이 막힘
  • 해결방법: gradient 영역에 pointer-events: none; 으로 설정하기
    • pointer-events: none; 으로 속성을 설정하면 해당 요소가 마우스 이벤트를 받지 않도록 되어서 마우스 이벤트가 해당 요소를 뚫고 다음에 있는 하위 요소에 전달
    • 하위 요소에 스크롤 기능이 적용되지 않고 스크롤이 동작하지 않음.
    • **pointer-events: none;**를 설정하면 해당 요소와 그 안의 하위 요소들 모두에 대해 마우스 이벤트가 무시(따라서 스크롤 동작도 불가능)

느낀점

  • Styled 컴포넌트를 사용해 하단모달을 구현하면서 뛰어난 재사용성을 느끼고 있다.

Untitled (5)

  • 모달 내부에서 재사용 가능한 요소들을 Styled Component로 만들어보려고 노력
  • 모달 내부에 보여지는 선택한 옵션에 대한 정보를 보여주는 커다란 Box
  • Box내부는 다시 HeaderSelection의 리스트로 이루어짐
// Box 컴포넌트
    
function Estimate() {
  return (
    <Wrapper>
      <Header>
        <OptionText>팰리세이드 Le Blanc (르블랑)</OptionText>
        <Price>+ 43,460,000원</Price>
      </Header>
      <SelectionList>
        <Selection></Selection>
        <Selection></Selection>
        <Selection></Selection>
      </SelectionList>
    </Wrapper>
 );
}
function Selection() {
  return (
     <Wrapper>
       <Option>
         <OptionTitle>파워트레인</OptionTitle>
         <OptionName>디젤 2.2</OptionName>
       </Option>
       <OptionPrice>+ 1,480,000 원</OptionPrice>
     </Wrapper>
  );
}
    
export default Selection;
    
const Wrapper = styled.div`
  display: flex;
  justify-content: space-between;
  width: 100%;
  div {
    ${Body2_Regular}
  }
`;
    
const Option = styled.div`
  display: flex;
  width: 215px;
`;
    
const OptionTitle = styled.div`
  color: ${colors.Cool_Grey_003};
  flex: 16;
`;
    
const OptionName = styled.div`
  color: ${colors.Cool_Grey};
  flex: 27;
`;
    
const OptionPrice = styled.div`
  color: ${colors.Cool_Grey};
  float: right;
`;
  • Selection과 같은 경우 내부의 텍스트들이 줄맞춤이 되어있음
  • 텍스트마다 div로 감싸서 flex로 위치를 배치

고민한 내용

// Content Wrapper
const Wrapper = styled.section`
  width: 100%;
  flex-grow: 1;
`;
    
// content/OptionImage
    
function OptionImage({url}: ImageProps) {
  const wrapperRef = useRef<HTMLDivElement>(null);
    return (
      <Wrapper ref={wrapperRef} currHeight={wrapperRef.current?.clientHeight}>
        <img src={url}></img>
      </Wrapper>
    );
}
    
export default OptionImage;
    
const Wrapper = styled.div<{currHeight: any}>`
  ${flexCenter}
  overflow: hidden;
  flex: 6;
  height: 100%;
  img {
    height: auto;
    max-height: ${(props) => props.currHeight}px;
  }
`;
  • 함께 고민했던 내용으로, 이미지의 크기가 너무커서 왼쪽 영역을 벗어나는 경우 처리방식 고민
  • 프로그래스바 밑 부분 Content영역의 높이를 flex-grow: 1;로 동적으로 주어서 높이값이 고정되지 않음
  • 이미지의 높이가 현재 차지하고 있는 Content보다 클 경우 프로그래스바의 높이가 줄어드는 문제 발생
  • Content의 높이를 동적으로 생성하는 것을 유지하면서 이미지 높이를 고정하고 싶었음
  • 옵션카드의 자세히보기를 구현할 때 사용했던 useRef를 이용해서 현재 높이를 wrapperRef.current?.clientHeight로 가져와서 img의 최대높이 고정
  • 이미지가 Content보다 커질 경우에도 x축은 overflow: hidden으로 감추고 높이는 고정시켜서 레이아웃의 변화를 막음

context api 사용

import React, {useState, createContext} from 'react';
    
export const OptionContext = createContext({
  option: 0,
  setOption: (option: number) => {}, // 초기값으로 빈 함수 설정
});
    
interface OptionProviderProps {
  children: React.ReactNode;
}
    
const OptionProvider = ({children}: OptionProviderProps) => {
  const [optionState, setOptionState] = useState<number>(0);
    
  const setOption = (option: number) => {
    if (option === -1) return;
    else if (option === 7) return;
    setOptionState(option);
  };
    
  const contextValue = {
    option: optionState,
    setOption: setOption,
  };
    
  return (
    <OptionContext.Provider value={contextValue}>
      {children}
    </OptionContext.Provider>
  );
};
    
export default OptionProvider;
import {OptionContext} from '@/provider/optionProvider';
    
const {option, setOption} = useContext(OptionContext);
    
   <OptionSwitcher>
      <PrevOptionButton onClick={() => setOption(option - 1)}>
        이전
      </PrevOptionButton>
      <NextOptionButton onClick={() => setOption(option + 1)}>
        선택 완료
      </NextOptionButton>
   </OptionSwitcher>

component 재사용

Untitled (7)
Untitled (8)
  <Trim.OptionWrapper>
    <ModelOption name="핵심 옵션" />
    <ModelOption name="외장 색상" />
    <ModelOption name="내장 색상" />
  </Trim.OptionWrapper>