React.Children

alajillo·2021년 10월 13일
1

React

목록 보기
11/12
post-thumbnail

React.Children

Children

const Parent = ({children}) => {
  return <div>{children}</div>
}

const GrandParent = ()=> {
  return <Parent><Box/></Parent>
}

여기서 Box컴포넌트가 Parent 컴포넌트에서 인자로 받고 있는 children이다. 컴포넌트 태그 의 자식 컴포넌트 혹은 태그로 들어오는 값을 받을 수 있다.

React 컴포넌트의 props(인자)

const Component = (props) => {
  console.log(props);
}

const Container = ()=>{
  return (
    <div>
      <Component type="vertical",size={34}>
        <Child/>
        <Child/>
        <Child/>
      </Component>
    </div>
  )
}

이런 코드를 작성했다고 했을때 Component가 인자로 받는 것은 다음과 같다.

기본적을 children property가 자동적으로 생성되고 나머지는 컴포넌트의 속성으로 넣어준 값들이 들어간다. 그렇기 때문에 구조분해 구조 할당을 통해서 children과 여러가지 props들을 받을 수 있다.

React.Children

여기서 React.Children은 다양한 메서드들을 지원한다.

React.Children.map

React.children.map(children, (child)=>{console.log(child)})

기본적인 사용법은 이렇게 된다. React.Children.map을 Array.prototype.map과 비슷하다.
React.Children.map는 인자를 두개를 받고 첫번째 인자는 자식 컴포넌트인 children을 넣어주고 두번째 인자는 children컴포넌트가 여러개일 경우 map과 동일하게 children 배열을 하나씩 꺼내서 인자로 받는 함수이다.
인자로 받는 것을 출력하면 이런 식이다.

이게 리액트의 돔 객체이다. 여러가지 속성중에서 $$typeof라는 속성이 있고 값으로 Symbol객체가 들어가 있다.

Symbol객체를 넣은 이유?

Symbol객체를 넣은 이유는 보안 때문이다. XSS라는 보안 공격이 있는데 XSS를 간단하게 얘기하면 document.body.innerHTML을 이용해서 유저의 입력값을 JSON을 통해서 api를 통해서 서버를 거쳐서 db에 저장이 된다. 그리고 다른 유저가 db에 저장된 값을 불러와서 렌더링이 된다고 했을때 만약에

<button onClick="fetch(~~~~)"></button>

이런 값을 저장하면 다른유저가 봤을때는 버튼이 하나 생성되고 그 버튼을 누르면 사용자의 정보가 탈취되는 상황이 일어난다. 이게 XSS공격이다.
여기서 React의 dom객체의 Symbol은 어떻게 이 방어를 방어할까?
간단하게 JSON내부에는 Symbol객체를 넣을수 없다. 그렇기 때문에 인위적으로 react의 dom객체를 넣었다고 해도 그 dom객체에는 Symbol 객체를 넣을수 없기 때문에 렌더링 되지 않는다.

다른 값들은 기본적으로 되어있는 설정값들과 useRef를 썼을때 표시되는 값 ref, props들이 있다.

이렇게 React.Children.map는 새로운 배열을 반환한다.

React.Children.forEach

React.Children.map과 동작은 똑같지만 다른점은 새로운 배열을 반환하지 않는다.

React.Children.count

const amount = React.Children.count(children);
console.log(amount) // 자식 컴포넌트의 갯수 출력

React.Children.only

const isOnly = React.Children.only(children);
console.log(isOnly) // 자식 컴포넌트가 하나 일경우 true 반환

React.Children.toArray

const childrenArray = React.Children.toArray(children)
console.log(childrenArray) // 자식 컴포넌트를 배열로 반환

React.Children.toArray는 왜있지..?

React.Children.map이랑 forEach만 있어도 충분할거 같은데 toArray는 굳이 있어야 할까?
필요한 상황은 다음과 같다.

const arr = [1,2,3,4]
arr.forEach((item,index,array)=>{
  console.log(item,index,array);
})

React.Children.forEach(children,(child,index,array)=>{
  console.log(child,index,array);
})

두가지 경우를 살펴보면 알수 있는데 배열의 prototype인 forEach의 경우에는 인자를 최대 3개 까지 받을 수 있지만 React.Children.forEach의 두번째 인자로 받는 함수는 3번째 인자를 받지 못한다.
즉 만약에 배열의 전체를 callback함수 내부에서 사용해야 할 경우에 toArray를 통해 배열로 만들고 Array.forEach를 통해서 전체 배열의 값에 접근하여 활용할수 있다.

profile
Developer's High

0개의 댓글