엘리먼트는 리액트 애플리케이션의 가장 작은 빌딩 블럭입니다. 이 페이지에서는 전용 JSX 문법을 사용해 React.element
를 어떻게 조작하는지 설명합니다.
참고 여기서는 여러분의
bsconfig.json
설정이"reason": { "react-jsx": 3 }
로 설정되어 있다고 가정합니다. 그렇지 않으면 JSX가 React 특정 형식으로 변환되지 않습니다.
기본 엘리먼트
첫 리액트 엘리먼트를 만들어보죠!
let element = <h1> {React.string("Hello World")} </h1>
element
바인딩과 {React.string("Hello World")}
표현식은 둘 다 리액트 애플리케이션 내에서 리액트 요소를 나타내는 기본 타입인 React.element
타입입니다. 엘리먼트는 애플리케이션을 DOM에 렌더링 할 때마다 화면에 표시되는 내용을 설명합니다.
children
과 같은 다른 리액트 엘리먼트를 처리하는 함수를 만들고 싶다면 React.element
어노테이션을 작성해 사용하면 됩니다.
let wrapChildren = (children: React.element) => {<div><h1> {React.string("Overview")} </h1>children</div>}wrapChildren(<div> {React.string("Let's use React with ReScript")} </div>)
React.element
타입은 ReactDOM.render(element, ...)
등 리액트 API 에서 많이 사용되기 때문에, 정의를 이해하는 것은 필수적입니다. JSX는 문자열
을 React.element
로 자동으로 변환해주지 않습니다. (리스크립트는 이 타입 변환을 명시적으로 강제합니다). 예를 들어 <div> Hello World </div>
의 경우는 타입 검사를 하지 않습니다. (which is actually a good thing because it's also a huge source for subtle bugs!), 여러분은 우선 "Hello World"
에 React.string
함수를 사용해야합니다.
다행히 리스크립트의 리액트 바인딩은 관련 데이터 유형을 모두 React.element
변환하는 기능을 제공합니다.
JSX 와 엘리먼트 사용하기
JSX를 이용하는 복잡한 엘리먼트 합성을 할 수 있습니다.
let greeting = React.string("Hello ")let name = React.string("Stranger");/* element 의 type은 React.element 입니다 */let element = <div className="myElement"> greeting name </div>
JSX는 리액트 애플리케이션의 엘리먼트 트리를 표현하는 주요한 방법입니다.
때때로, 기존 리액트 코드베이스와 상호 운용을 수행할 때 구문 제한으로 JSX 구문을 사용할 수 없는 상황에 놓이게 될 때도 있습니다. 이럴 때의 해결방법은 나중에 이스케이프 해치 챕터를 확인하세요.
엘리먼트 만들기
문자열, 정수, 실수, 배열로부터 엘리먼트 만들기
리액트 엘리먼트나 리액트 컴포넌트를 만들기 위해 JSX를 사용하는 것 외에도 React
모듈은 기본 데이터 유형에서 엘리먼트를 생성하는 다양한 함수를 제공합니다.
React.string("Hello") /* "Hello"를 표시하는 새 엘리먼트 */React.int(1) /* "1"을 표시하는 새 엘리먼트 */React.float(1.0) /* "1.0"을 표시하는 새 엘리먼트 */
또한 여러 엘리먼트를 단일 요소로 표현하는 React.array
함수를 제공합니다. (리스트 데이터나 자식 엘리먼트를 통과시킬 때 유용합니다)
let element = React.array([React.string("element 1"),React.string("element 2"),React.string("element 3")])
참고 list
는 런타임 오버 헤드를 포함하기 때문에 React.list
함수는 제공하지 않습니다. 리스크립트는 깔끔하고 관용적인 자바스크립트 출력에 더 관심있습니다. 엘리먼트 list
를 단일 리액트 엘리먼트로 변경하려면 Belt.List.toArray
와 React.array
를 함께 사용하세요.
Null 엘리먼트 만들기
리스크립트는 강한 타입 특성에서 생기는 제약조건이 있기 때문에 element || null
같은 타입을 허락하지 않습니다. 값이 렌더링 되거나 렌더링 되지 않을 수 있는 조건을 표현할 때마다 Nothingness를 나타내는 React.null
상수가 필요합니다.
let name = Some("Andrea")let element = switch name {| Some(name) => <div> {React.string("Hello " ++ name)} </div>| None => React.null}<div> element </div>
이스케이프 해치
참고 이 챕터에서는 JSX 자체에서 사용하는 저수준 API를 다룹니다. 저수준 API는 특정 JSX 구문 제한에 도달할 때 사용해야합니다. JSX 내부에 대한 자세한 정보는 JSX를 넘어서 섹션에서 찾을 수 있습니다.
컴포넌트 함수를 통한 엘리먼트 생성
참고 컴포넌트와 Props에 대한 상세한 부분은 컴포넌트와 Props 챕터에 설명되어있습니다.
때로는 React.element
생성을 더 잘 제어하기위해 구성 요소 함수를 전달하는것이 필요합니다. React.createElement
함수를 사용해 엘리먼트를 인스턴스화 하세요.
type props = {"name": string};let render = (myComp: props => React.element) => {<div>{React.createElement(myComp, {"name": "Franz"})}</div>}
이 기능은 기존 리액트JS/자바스크립트와 상호작용할 때 종종 사용됩니다. 순수 리스크립트 리액트 애플리케이션은 렌더링 함수를 전달하는 것이 좋습니다("render prop" 이라고 불리기도 하죠).
let render = (renderMyComp: (~name: string) => React.element) => {<div>{renderMyComp("Franz")}</div>}
가변 Children 넘기기
세 번째 매개 변수로 자식 배열을 받는 React.createElementVariadic
함수가 있습니다.
type props = {"title": string, "children": React.element};let render = (article: props => React.element) => {let children = [React.string("Introduction"), React.string("Body")];let props = {"title": "Article #1", "children": React.null};{React.createElementVariadic(article, props, children)}}
참고 여기서 우리는 타입 검사를 만족시키기 위해 "children": React.null
을 prop으로 전달합니다. 리액트는 children props 을 무시하고 children array 를 더 선호합니다.
이 함수는 주로 JSX 변환에 이용됩니다. 그래서 일반적으로는 React.createElement
를 사용하고 대신 children prop을 넘겨줍니다.
DOM 엘리먼트 만들기
DOM 엘리먼트(<div>
, <span>
, etc.)를 만들기 위해서는, ReactDOMRe.createDOMElementVariadic
함수를 사용합니다.
ReactDOMRe.createDOMElementVariadic("div", ~props=ReactDOM.domProps(~className="card", ()), []);
위 함수에는 ReactDOM.domProps
생성 함수가 필요합니다. 그렇기 때문에 리스크립트는 유효한 dom props만 전달하는지 확인할 수 있습니다. ReactDOM 모듈에서 사용가능한 모든 Props 목록을 찾을수 있습니다.
경고: The ReactDOMRe
모듈은 다음 rescript-react
메이저 릴리즈에서 제거될 예정이므로 사용에 주의하세요!
엘리먼트 복제
참고 이건 이스케이프 해치입니다. 기존 JS 코드/라이브러리의 상호운용에만 유용합니다.
새 인스턴스에 prop 값을 덮어 씌우거나 추가하기 위해 기존 엘리먼트를 복제해야하거나 data-name
같은 유효하지 않은 prop 이름 설정이 필요한 경우가 있습니다. 이 때 React.cloneElement
를 사용할 수 있습니다.
let original = <div className="hello"/>/* className이 "world"로 설정 된 새 React.element 가 반환됩니다. */React.cloneElement(original, {"className": "world", "data-name": "some name"});
위에서 언급한 기능은 리액트JS 코드베이스에서 일반적으로 사용되는 props spreading
처럼 사용할 수도 있지만 안전하지 않은 특성과 부정확함으로 인해 props spreading 처럼 사용하는 것은 완전 비추합니다. (예: 정의되지 않은 props 컴포넌트에 추가하는 것은 넌센스이고 버그를 찾기 어렵게 만듭니다)
리스크립트에서는, 필요한 Props 를 컴포넌트에 명시적으로 전달하거나 renderProps을 사용합니다. 우리는 props를 보다 편리하게 전달하기 위해 JSX punning 구문을 도입했습니다.