프론트엔드 - 6

송현섭 ·2023년 3월 21일

프론트엔드

목록 보기
7/24
post-thumbnail

props drilling


  • props가 자식에게 넘겨주는 단계가 두 단계 이상 될 경우를 props drilling 라고 함

  • props drilling 이 과도하면 코드 가독성, 유지보수가 어렵기에 가급적 방지할 수 있도록 하고, 이런 방지를 위해 global state 를 사용하는 것이 좋음






Emotion에 props 전달하기


  • emotion으로 만든 태그에도 props를 전달할 수 있음





	return (
		<>
			<Test isTrue={isTrue} onClick={handleOnClick}>클릭하면 색이 왔다 갔다</Test>
		</>
	);
  • 위와 같이 isTrue={isTrue} 로 emotion(Test)에 변수 값을 전달할 수 있음

*상위컴포넌트에서 하위컴포넌트로 변수,함수 등을 전달하여 하위컴포넌트에서 이를 props로 받아 사용하는 것과 같은 방법





export const Test = styled.div`
	color: ${(props) => (props.isTrue ? 'red' : 'blue')};
`;
  • 이후 emotion(Test)에서 이 값을 props로 받아옴

  • 속성 값 자리에 익명 화살표 함수를 만들고 위와 같이 삼항연산자를 이용해서 조건에 맞게 색상이 바뀌는 효과 적용 가능


    +a)
    -emotion의 props 전달은 템플릿 리터럴을 생각하면 됨

    -백 틱 안에서 변수는
    ${ } 로 표시하듯 emotion의 css 속성 안 백틱 안에서 자바스크립트 변수(props)를 가져오는 것






state의 리렌더


  • setState( ) 는 실행되면서 ( )안에 할당되어 있는 값으로 바꿀 때 값만 바꾸는 것이 아니라 리렌더링까지 진행함 (JSX 자체를 다시 그려내서 화면에 표출)
    *리렌더 되는 상황 =(새로운 props 들어올 때, 부모 컴포넌트 렌더링 될 때, state 값 바뀔 때...등)


  • 하지만 위와 같이 setState( )가 많을 때, 각각의 값이 바뀔 때마다 리렌더링을 하게 되기 때문에 비효율적임

  • 따라서 setState( ) 는 값을 바뀌면 코드를 전부 읽은 후 해당 값을 바꾸면 임시 저장소에 넣어 둠. 이처럼 각각의 setState( ) 가 위치해 있는 함수, 코드를 전부 읽은 후의 최종 저장된 값을 바뀌는 값으로 변경하고 1번 렌더링 함(1번만 렌더링하면서 모든 지정값을 바꾸기에 효율적)




+a) setState( ) 는 비동기적으로 작동

export default function stateTest(){
const [value,setValue]=useState(0)

const onClick = () => {
    setValue(value+1)
    setValue(value+1)
    setValue(value+1)
  }

  return (
    <div className="App">
      <button onClick={onClick}>+</button>
      <h1>{value}</h1>
    </div>);
}
  • [반복해서 실행할 경우 마지막 실행 값이 최종 적용됨]








state 리렌더 - 예제를 통한 이해

   function onChangeWriter(event) {
  
        setWriter(event.target.value)

        if(writer && title && contents) {

          setIsActive(true)
        }
    }
  
  
    function onChangeTitle(event) {
  
      setTitle(event.target.value)

      if(writer && title && contents) {

        setIsActive(true)
      }
  }
  
  
  function onChangeContents(event) {
  
    setContents(event.target.value)

    if(writer && title && contents) {

      setIsActive(true)
    }
  } // 함수가 끝나고 setContents에 입력값이 재할당되면서 리렌더 되는데 그 전에 if문을 검사할 경우
    // setIsActive는 false가 되서 결국 버튼 색깔이 안 바뀜
  1. 위 코드에서 writer, title, contents 라는 입력값을 순서대로 입력할 경우 먼저 writer의 변경값을 확인 후 코드를 전부 읽고 임시 저장소에 넣어 둠

  2. 다음 순서대로 title의 변경값을 확인하고 코드를 전부 읽은 다음, 임시 저장소에 넣어 둠

  3. 마지막으로 contents의 변경값을 확인하고 저장소에 넣어뒀지만 함수(코드) 읽기가 끝나기 전(값이 최종적으로 변경되기 전)이기 때문에 if문의 조건에 해당되지 않아 setIsActive(true) 가 실행되지 않음!





state 리렌더 - [해결방안]

      function onChangeWriter(event) {
  
        setWriter(event.target.value)

        if(event.target.value && title && contents) {

          setIsActive(true)
        }
    }
  
  
    function onChangeTitle(event) {
  
      setTitle(event.target.value)

      if(writer && event.target.value && contents) {

        setIsActive(true)
      }
  }
  
  
  function onChangeContents(event) {
  
    setContents(event.target.value)

    if(writer && title && event.target.value) {

      setIsActive(true)
    }
  } 
  • 위와 같이 각 함수의 조건문에 변경 값을 event.target.value로 지정
    [어느 값을 마지막에 입력하든 상관 없이, event.target.value 는 이벤트감지로 발생하는 값이라 변경값이 바로 반영되어 로직이 정상 구동됨]
    (setState로 변경한 값이 아니라 코드를 전부 읽고 변경되지 않음)






+a) Use State 와 리렌더링

  • useState 로 만든 변수에 담기는 데이터는 리렌더링 되어도 유지됨

    ex.
    count=count +1
    const [count] = useState(0) 일 경우

  • 1,2,3,4,5...증가하고 리렌더링 되어도 이 값은 그대로 담겨있음
    [즉, 변경된 값이 저장됨]

profile
막 발걸음을 뗀 신입

0개의 댓글