React 16에 추가된 기능이 나왔는데 사람들이 많이 사용하지 않음. 좋은 기능이 있는데…
Return Types Strings and Fragments
이전 component는 null인게 규칙이었다.
component 아니면 null이어서 string같은 type을 return할 수 없었다.
return할 때, 하나가 아닌 두 개를 리턴하고 싶을 때도 있다.
// 예전 react에서는 하나의 element로 묶어야 했다.(react가 여러 개를 한 번에 return하지 못하니까)classReturnTypesextendsComponent{render(){return(<header></header><div></div><footer></footer>);}}// 이렇게 사용하고 싶다면 예전에는 array(key를 넘겨줒교)나 span을 이용했다.return([<headerkey={1}></header>,<divkey={2}></div>,<footerkey={3}></footer>]);
또는
// 거의 대부분의 리액트 프로젝트가 이렇게 되어있지만, 그룹핑을 해야 하기 때문에 별로다...return(<span><header/>,<div/>,<footer/>,</span>);// 불필요한 코드가 많다.// span을 사용하면 html코드에 span이 잡히고, css도 꼬일 수 있다.
React 16에서는 fragments라는 걸 활용할 수 있다.
import React,{ Component, Fragment }from'react';classReturnTypesextendsComponent{render(){return(<Fragment><header/>,<div/>,<footer/></Fragment>);}
또는
return(// Fragment 생략 가능(create-react-app은 아직 지원하지 않음, webpack은 정상 작동)<><header/><div/><footer/></>);
return string도 가능하다.
// App.jsimport React,{ Component, Fragment }from'react';classReturnTypesextendsComponent{render(){return'Hello';}}classAppextendsComponent{render(){return(<Fragment><ReturnTypes/></Fragment>);}}exportdefault App;// 화면에 Hello가 출력됨
Portals
react.js는 div를 찾아서 mount하는데… index.js에 있는 root id를 mount한다. 그런데, 가끔은 리액트 루트 밖에서 터치하고 싶은 경우가 있다.(css의 색상 테마 등등…)
Portals를 사용하면 리액트 루트 밖에 리액트를 넣을 수 있게 해준다.
다른 페이지에서 로딩할 때 우용(iframe이거나 혹은 html을 변경하지 못할 때, 워드프레스 작업을 할 때, 리액트 플러그인을 만들 때 등등…)
<!-- index.html --><body><noscript>
You need to enable Javascript to run this app.
</noscript><!-- react scope 밖에 위치해 있다.(정적인 html) --><header> // this
<h1>Can't touch this</h1></header><divid="root"></div></body>
portals 사용 예는 다음과 같다.
<!-- index.html --><body><noscript>
You need to enable Javascript to run this app.
</noscript><header><h1>Can't touch this</h1><spanid='touchme'></span></header><divid="root"></div></body>
// App.jsimport{ createPortal }from'react-dom';classPortalsextendsComponent{// render를 통해 element가 아닌 Portal(react dom안에 위치해 있음)을 returnrender(){returncreatePortal(<Message/>,// Portal에게 어디에 마운트해야 할지 알려줘야 한다.
document.getElementById('touchme'););}}constMessage=()=>"Just touch it!";classAppextendsComponent{render(){return(<Portals/>);}}exportdefault App;
Error Boundaries
컴포넌트가 자식 컨포넌트의 에러를 관리할 수 있게 해준다.
자식 컴포넌트에 대한 에러에게만 한정되는 기능이다.
에러를 구분하고, 에러에 대응할 수 있다.
// 보편적인 에러를 만들어보겠다.classErrorMaker extneds Component {
state ={
friends:["test","one","two","three"];};componentDidMount=()=>{setTimeout(()=>{this.setState({ friends: undefined });},2000);};render(){const{ friends }=this.state;return friends.map(friend =>` ${friend} `);// error}}constErrorFallback=()=>"Sorry something want wrong";classAppextendsComponent{
state ={ hasError:false}ComponentDidCatch=(error, info)=>{
console.log(`catched ${error} the info i have is ${JSON.stringify(info)}`);this.setState({ hasError:true});}render(){const{ hasError }=this.state;return({hasError ?<ErrorFallback/>:<ErrorMaker/>})}}
컴포넌트마다 if/else 구분이 있도록 개발하면 안된다. 이 문제는 HOC로 해결한다.
Error Boundaries with Higher Order Components(HOC)
에러 관리법
constBoundaryHOC= ProtectedComponent =>classBoundaryHOCextendsComponent{
state ={ hasError:false};componentDidCatch=()=>{this.setState({ hasError:true});}render(){const{ hasError }=this.state;if(hasError){return<ErrorFallback/>}else{return<ProtectedComponent/>}}}exportdefaultBondaryHOC(App);// 우리가 만들 BoundaryHOC로 컴포넌트 보호
this.setState(null)
상태를 null로 바꾸는 것
리액트 development process에서 컴포넌트를 업데이트하고 싶지 않을 때 사용
// 피자가 20까지만 상태 변경이 되도록 하는 예제(return null 활용)import React,{ Component }from'react';const MAX_PIZZAS =20;consteatPizzas=(state, props)=>{const{ pizzas }= state;if(pizzas < MAX_PIZZAS){return{
pizzas = pizzas +1}}else{returnnull;}}classControlledextendsComponent{
state ={ pizzas:10};render(){const{ pizzas }=this.state;return(<ButtononClick={this._handleClick}>{`I habe eaten ${pizzas}${pizzas ===1?"pizza":"pizzas"}`}</Button>);}_handleClick=()=>{this.setState(eatPizzas);}}
댓글
댓글 쓰기