React.js 조건부렌더링,list&key,form,공통state,composition
27 Jan 2021 | ReactReact.js 조건부렌더링,list&key,form,공통state,composition
-
Conditional Rendering
- 조건에 따라 UI를 감추거나 보여주거나하는 테크닉
- Element Variable : 변수에 리액트의 element를 담아서 사용할 수 있다
let button = <ComponentName><ComponentName />; // 사용 예시 <div> {button} </div>
- && 연산자와 short-circuit 현상을 이용한 방법
const = messages = ['React', 'hi', 'hello']; // props로 전달 //function component function Mailbox(props) { const unreadMessage = props.unreadMessage; return { <div> {unreadMessage.length > 0 && <h2> you have {unreadMessage.length} unread Messages. </h2> } </div> }; }
- 삼항연산자를 이용한 방법
render() { const isLoggedIn = this.state.isLoggedIn; return { <div> The user is {isLoggedIn ? 'currently' : 'not'} logged in. </div> } }
- null을 return하여 렌더링 막기
function WarningBanner(props) { if(!props.warn) { return null; } return ( <div> Warning! </div> ) }
-
Lists and keys
- 리액트에서는 배열을 이용해서 다수의 element를 렌더링할 수 있다
function NumberList(props){ const numbers = props.numbers; const listItems = numbers.map((number) => <li>{number}</li>); return( <ul>{listItems}</ul>); } const numbers = [1,2,3,4,5]; render( <NumberList numbers={numbers}></NumberList>);
- 두 list 사이에서는 key가 같아도 상관없다
- 리액트에서는 배열을 이용하여 UI를 생성할 경우 key라는 별도의 식별자가 필요
- but, key값은 리액트 자체적인 식별자로 쓰이기 때문에 사용자가 접근 할 수 없다. 따라서 식별자가 필요한 경우 id 등 별도로 지정을 해주어야한다
function ListItem(props) { return <li>{props.value}</li>; } function NumberList(props){ const numbers = props.numbers; const listItems = numbers.map((number) => <ListItem key={number.toString()} value={number}></ListItem>); return( <ul>{listItems}</ul>); }
- JSX 안에서 map 사용하기
function NumberList(props) { const numbers = props.numbers; return ( <ul> {numbers.map((number) => <ListItem key={number.toString()} value={number})} </ul>); }
-
Forms
- Controlled Component : 리액트의 통제를 받는 input form element
handleChange(e) { this.setState({value: e.target.value}); } render() { return ( <form> <input type='text' value={this.state.value} onChange={this.handleChange}></input> </form>) }
- ES6의 객체의 계산된 프로퍼티 이름(computed property name)를 이용해서 setState의 key값에 맞는 value를 바꿀 수 있다
handleChange(e) { const target = e.target; const value = target.value; const name = target.name; // 선택한 target의 계산된 이름 [name] this.setState({ [name]: value }) }
- null 값을 이용하여 행동 제어
ReactDom.render( <input value='hi'></input>, mountNode); setTimeout(() => { // 1초 뒤에 입력가능 상태로 바뀜 ReactDom.render( <input value={null}></input>, mountNode); }, 1000);
-
Lifting State Up
- Shared State : 상위 컴포넌트의 state를 여러 하위 컴포넌트에서 공통적으로 사용
- 상위 컴포넌트에서 이벤트를 설치하고 값을 받을 매개변수를 세팅
- 이벤트는 props로 넘겨준다
- 하위 컴포넌트에서 this.props.이벤트(인자)로 인자를 상위 컴포넌트의 매개변수로 전달한다
-
Composition vs Inheritance
- Composition : 여러 개의 컴포넌트를 합쳐서 새로운 컴포넌트를 만드는 것
- Containment : sidebar, dialog 등 box 형태의 컴포넌트는 자신의 하위 컴포넌트를 미리 알 수 없기에 children이라는 prop을 사용해서 조합한다
function FancyBorder(props) { return ( <div> {props.children} </div> ); }
function WelcomeDialog() { return ( <FancyBorder> // Children으로 전달 <h1>Welcome</h1> <p>Thank you</p> </FancyBorder> ); }
- children이 여러개의 집합인 경우에는?
- 상위 컴포넌트에서 각각 렌더링할 컴포넌트를 넣어준다
function SplitPane(props) { return ( <div> <div> {props.left} </div> <div> {props.right} </div> </div> ); }
function App() { return ( <SplitPane left={ <Contacts></Contacts> } right={ <Chat></Chat> } ); }
- 객체지향 언어에서는 상속을 통해 Specialization을 구현한다
- but, 리액트에서는 Composition을 사용하여 Specialization을 구현한다
function Dialog(props) { return ( <FancyBorder> <h1>{props.title}</h1> <p>{props.message}</p> </FancyBorder> ); }
function WelcomeDialog() { return ( <Dialog title='Welcome' message='Thank you' ></Dialog> ); }