Archive

React.js 조건부렌더링,list&key,form,공통state,composition

|

React.js 조건부렌더링,list&key,form,공통state,composition


  1. 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>
        )
    }
    


  2. 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>);
    }
    


  3. 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);
    


  4. Lifting State Up

    • Shared State : 상위 컴포넌트의 state를 여러 하위 컴포넌트에서 공통적으로 사용
    • 상위 컴포넌트에서 이벤트를 설치하고 값을 받을 매개변수를 세팅
    • 이벤트는 props로 넘겨준다
    • 하위 컴포넌트에서 this.props.이벤트(인자)로 인자를 상위 컴포넌트의 매개변수로 전달한다


  5. 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>
        );
    }
    




참고 자료


reactjs.org - 공식홈페이지

goormedu - 처음만난 리액트