반응형

함수형에 state를 쓸수있게된것은 최근의 이야기이고 그전에는 상태관리나 다른 기능들을 모두 클래스형을 썻기 때문에  아직도 예전에 만들어진 리액트코드들을 보면 클래스형 으로 만들어진것들이 있다고한다.

혹시라도 이것을 유지보수 할일이생긴다면 최소한 코드를 읽고 이해할수는 있어야하기에 과거의 유물도 배워야하는,..

(개발자 그들은대체...) 그래서 클래스 형을 공부해보려고 한다.

 

ClassComponent.js

import React, { Component } from 'react';

class ClassComponent extends Component{
    render(){
        return(
            <div>
                클래스형 컴포넌트 입니다
            </div>
        )
    }
}

export default ClassComponent

우선 클래스형 컴포넌트는 이런 형식으로 작성하면된다. 위에 import하는부분에 컴포넌트라는것이 추가로 생겻고

함수형컴포넌트에서 함수를 만들어준것과 달리 클래스형 컴포넌트는 클래스를 만들면된다. (파일이름과같은)

정말 기본적인 형태만 가진 클래스형 컴포넌트이다. 클래스 형에서는 렌더메소드를 사용해서 JSX를 반환시켜준다.

App.js

import ClassComponent from './components/ClassComponent';

function App() {
  return (
      <ClassComponent/>
    );
}

export default App;

app.js에서 import해서 사용하는 방법은 똑같이 사용하면된다.

 

 

클래스형 컴포넌트 Props사용 

클래스형에서 props를 사용할때에는 this.props를 사용하면 app.js에서 보내준 props값을 조회할수있다

 

우선은 App.js에서 props값을 보내줘보겠다.

 

App.js

function App() {
  return (
      <ClassComponent color="blue" name="colazoa" isSpecial/>
    );
}

 

{color : "blue" , name : "colazoa" isSpecial = {true} } 이런 객체의 형태로 props가 보내지고

 

ClassComponent.js

class ClassComponent extends Component{
    render(){
        const { color, name , isSpecial} = this.props   
        
        return(
            <div style={{color}}>
                클래스형 컴포넌트 입니다{isSpecial && "😒"}
                <br/>안녕하세요 {name}
            </div>
        )
    }
}

클래스 컴포넌트에서는 this.props로 값을 받아서 객체 구조분해 할당을 해주고 있다

(render메소드 안에서 해야함)

할당된 변수들을 넣어서 사용할수있다.

 

함수형과 똑같이 props에 default를 설정해줄수도 있다.

import React, { Component } from 'react';

class ClassComponent extends Component{
    render(){
        const { color, name , isSpecial} = this.props;

        return(
            <div style={{color}}>
                클래스형 컴포넌트 입니다{isSpecial && "😒"};
                <br/>안녕하세요 {name}
            </div>
        )
    }
}
ClassComponent.defaultProps = {
    name: '이름없음',
    color: 'turquoise',
    isSpecial:false
};
export default ClassComponent

요로케 넣어주면 App.js에서 props를 보내주지 않았을 때에는 default되있는 props값들이 적용된다.

 

 

아니면 클래스에서는 다른방법으로 static키워드를 사용해서 디폴트값을 설정할수도있다.

import React, { Component } from 'react';

class ClassComponent extends Component{
    static defaultProps={
        name: '이름없음',
        color: 'turquoise',
        isSpecial:false    
    }
    render(){
        const { color, name , isSpecial} = this.props;

        return(
            <div style={{color}}>
                클래스형 컴포넌트 입니다{isSpecial && "😒"};
                <br/>안녕하세요 {name}
            </div>
        )
    }
}
// ClassComponent.defaultProps = {
//     name: '이름없음',
//     color: 'turquoise',
//     isSpecial:false
// };
export default ClassComponent

밑의코드는 주석처리를 해주고 static 키워드를 이용해서 default 값을 줬다. 결과화면은 똑같이 나온다.

 

이렇게 전부사용이가능하다면 클래스형을 함수형으로 바꿀수도 있고

함수형을 클래스형으로 바꿔줄수도 있다.

저번에 만든 카운터컴포넌트를 클래스형 컴포넌트로 다시 만들어보겠다.

class ClassCounter extends Component{
    render(){
        return(
            <div>
                <h1>0</h1>
                <button>+1</button>
                <button>-1</button>
            </div>
        )
    }
}

 

이렇게 클래스형으로 똑같이 만들어주고 이제 클래스형에서 상태값을 관리하는 방법을 알아보자!

class ClassCounter extends Component{
    handleIncrease(){
        console.log('increase')
        console.log(this)
    }
    handleDecrease(){
        console.log('decrease')
    }
    render(){
        return(
            <div>
                <h1>0</h1>
                <button onClick={this.handleIncrease}>+1</button>
                <button onClick={this.handleDecrease}>-1</button>
            </div>
        )
    }
}

함수형에서 안에 함수를 만들어줬던것처럼 클래스에서는 메서드를 만들어준다.(handleIncrease,handleDecrease)

이 상태에서는 함수에서 this키워드를 사용하면 undefined가 나온다

만든 메서드들을 각 button 들의 이벤트로 등록하게 되는 과정에서 각 메서드와 컴포넌트 인스턴스의

관계가 끊겨버리기 때문입니다.

 

그래서 이걸 다시 컴포넌트에 연결해주어야하는데

bind를 사용하는방법과 화살표함수를 사용하는 방법 2가지가있다.

 

bind를 사용해 this를 컴포넌트와 연결하는방법

class ClassCounter extends Component{
    constructor(props){
        super(props);
        this.handleIncrease = this.handleIncrease.bind(this);
        this.handleDecrease = this.handleDecrease.bind(this);        
    }
    handleIncrease(){
        console.log('increase')
    }
    handleDecrease(){
        console.log('decrease')
    }
    render(){
        return(
            <div>
                <h1>0</h1>
                <button onClick={this.handleIncrease}>+1</button>
                <button onClick={this.handleDecrease}>-1</button>
            </div>
        )
    }
}

 

bind를 사용하면 this가 무엇을가리킬지를 직접 설정할수있다.

constructor 에서는 props 파라미터로 받아오고 super(props) 를 호출해주어야 하는데,

이는 이 클래스가 컴포넌트로서 작동 할 수 있도록 해주는 Component 쪽에 구현되어있는

생성자 함수를 먼저 실행해주고, 우리가 할 작업을 하겠다 라는 것을 의미합니다. (예..?)

class ClassCounter extends Component{
    constructor(props){
        super(props);
        this.handleIncrease = this.handleIncrease.bind(this);
        this.handleDecrease = this.handleDecrease.bind(this);        
    }

일단 클래스를 만들때Component라는 클래스에서 상속받아서 만드는거고..

생성자 함수constructor에 props가 들어가서 부모요소인 Component의 props를 받아오고

이제 만들어놓은 메서드들을 ClassCounter컴포넌트에 바인드한다...

(완전히 이해한건아닌것같고 이렇게까지는 맞는건가..)

 

화살표함수를 사용해 this를 컴포넌트에 연결하는방법

import React,{Component} from 'react'

class ClassCounter extends Component{
    handleIncrease = () => {
        console.log('increase')
        console.log(this)
    }
    handleDecrease = () => {
        console.log('decrease')
    }
    render(){
        return(
            <div>
                <h1>0</h1>
                <button onClick={this.handleIncrease}>+1</button>
                <button onClick={this.handleDecrease}>-1</button>
            </div>
        )
    }
}

export default ClassCounter

이렇게 메서드를 화살표함수로 만들어도 this를 받아올수있다.

아니면 그냥 onClick에서 함수를 만들어서 사용하는것도 가능하다.

    render(){
        return(
            <div>
                <h1>0</h1>
                <button onClick={()=>{console.log("increase")
                console.log(this)}}>+1</button>
                <button onClick={()=>{console.log("decrease")
                console.log(this)}}>-1</button>
            </div>
        )
    }

이렇게도 사용이 가능은 한데 보기에도 별로고 렌더링할때마다 함수를새로만드는거기때문에

최적화도 힘들다고한다 추천하는 방법은 아닌것같다.

 

이제 메서드를 만드는방법들은 알았으니 상태값만있으면 된다.

상태값은 state를 선언해서 사용한다

 

state만들기 constructor로 만들때

    constructor(props){
        super(props)
        this.state{
            counter:0
        };
    }

이렇게 constructor안에 this,state로 상태값을 만들어주면 된다 클래스에서 state는 무조건 객체형태여야한다.

만들고 constructor안에 메서드도 bind연결 해주면된다.

 

화살표함수로 만들어서 생성자함수(constructor)를 쓰지않았다면. 

 

state만들기 (화살표함수로 메서드를 만든경우)

    stste={
        counter : 0
    }

그냥 이렇게 선언해줘도 문제없다.

 

이제여기서 상태값을 변경할때는 this.setState 를 사용해서 상태값을 변경해줄수있다.

 

ClassCounter.js

class ClassCounter extends Component{
    state={
        number:0
    };
    handleIncrease = () => {
        this.setState({
            number: this.state.number+1
        });
    };
    handleDecrease = () => {
        this.setState({
            number: this.state.number-1
        });
    };
    render(){
        return(
            <div>
                <h1>{this.state.number}</h1>
                <button onClick={this.handleIncrease}>+1</button>
                <button onClick={this.handleDecrease}>-1</button>
            </div>
        )
    }
}

this.setstate로 객체의 값을 변경시켜준다. state는 이 컴포넌트 안의 값이기때문에 바로 불러올수는없고 this키워드를 사용해서 this.state 그리고 키 값까지 써줘야 value 에 접근할수있다.

 

함수형업데이트

    handleIncrease = () => {
        this.setState(state=>({
            number: state.number+1
        }));
    };

함수에서 this.setState를 이렇게 써주는걸 함수형 업데이트라고 한다.

이렇게 쓰면 this.setState를 여러번사용할수있는 장점이있다.

    handleIncrease = () => {
        this.setState(state=>({
            number: state.number+1
        }));
        this.setState(state=>({
            number: state.number+1
        }));
    };

이렇게 사용이 가능하고 클릭을했을 때 2씩 증가하게된다

그냥 this.setState로 사용했을 때는 값에 1을 더해주는 작업을 두번주지만,

실제로 2가 더해지지지는 않습니다.

 

업데이트 할 객체를 넣어주는 setState 에서 2씩 더해지지 않는 이유는 setState 를 한다고 해서 상태가 바로 바뀌는게 아니기 때문입니다. setState 는 단순히 상태를 바꾸는 함수가 아니라 상태로 바꿔달라고 요청해주는 함수로 이해를 해야합니다 (참고). 성능적인 이유 때문에 리액트에서는 상태가 바로 업데이트 되지 않고 비동기적으로 업데이트가 됩니다.

(벨로퍼트에서 알려주는 내용입니다. 자세한내용은 벨로퍼트에 가시면 보실수있습니다.)

(저도 보고하는거에요ㅠㅠㅜ)

 

여튼 이렇게 카운터를 클래스형으로 바꿔보았다 시작을 한지 얼마 안되었지만 벌써함수형이 눈에익은건지 함수형은 좀 알아먹을만 했던것같은데 클래스형은 복잡하다는 생각이든다 가능하면 마주치지말자우리...

혹시 만나더라도 못본척지나가주라...(애절)

반응형
반응형

리액트에서 input 태그의 상태를 관리하는 방법 

인풋태그를 넣어서 사용할 컴포넌트를 하나 만들어준다 

 

InputSample.js

import React from 'react'

function InputSample(){


    return(
        <div>
            <input/>
            <button>초기화</button>
            <div>
                <b>값:</b>
            </div>
        </div>
    )
}

export default InputSample

InputSample컴포넌트를 App.js에서 렌더링해준다 

import InputSample from './components/InputSample';

function App() {
  return (
      <InputSample/>
    );
}

export default App;

그럼이렇게 화면이 나오게된다.

인풋에 입력하는 값이 아래의 값: 옆에 나오게하고

초기화 버튼을 누르면 인풋태그의 값이 지워지게 해줄것이다.

useState를 사용하여상태값이 변경될때마다 페이지의 값도 변하게 해준다

function InputSample(){
    const[input,setinput] = useState("") 
    const change = (e)=>{
        setinput(e.target.value)
    }
    const reset = ()=>{
        setinput("")
    }

    return(
        <div>
            <input value={input} onChange={change}/>
            <button onClick={reset}>초기화</button>
            <div>
                <b>값:{input}</b>
            </div>
        </div>
    )
}

 

이렇게 써주면 input태그의 값이변할때(onChange될때)  {change}함수가 실행되게 되고

change함수는 setinput으로 input상태의 값에 input 태그의 현재 입력되고있는 value를 넣어주게된다

결과적으로 input태그자체에 써져있는 밸류도 바뀌면서 아래에있는 값 : 옆에도

변경되는 input값이 들어가게된다.

 

button을 클릭하면 setinput(" ")이 실행되면서 input상태값은 공백이된다

입력한 값이 잘나오고 초기화를 누르면 초기화도 아주 잘된다 ^^ 항상 좀 이랬으면....

 

다시 이번에는 인풋을 여러개 넣고 사용해보겠다.

 

InputSample.js

function InputSample(){
    const change = (e)=>{
    }
    const reset = ()=>{
    }

    return(
        <div>
            <input placeholder='이름'/>
            <input placeholder='닉네임'/>
            <button onClick={reset}>초기화</button>
            <div>
                <b>값:</b>
                이름 (닉네임)
            </div>
        </div>
    )
}

input.js파일을 위처럼 수정해준다.

인풋이 2개인 화면이 만들어진다.

여기에 값두개를 인풋두개에 각각 관리할수있는 상태값으로 이름과 닉네임을 따로 띄워준다

function InputSample(){
    const[inputs,setInputs] = useState({
        name:'',
        nickname:''
    });
    const {name,nickname} =inputs; //inputs를 객체구조분해할당
    
    const change = (e)=>{
        const{value,name} =e.target //e.target=함수를실행시키는요소
                                    // 에서 name과 value값을 할당
        setInputs({
            ...inputs, //원래있던 인풋객체를 펼쳐서넣어줌
            [name]:value // name변수의 키를가진 값을 value로 설정
        });
    };

    const reset = ()=>{
        setInputs({
            name:"",
            nickname:'',
        });
    };

    return(
        <div>
            <input name='name' placeholder='이름' onChange={change} value={name}/>
            <input name='nickname' placeholder='닉네임' onChange={change} value={nickname}/>
            <button onClick={reset}>초기화</button>
            <div>
                <b>값:</b>
                {name} {nickname}
            </div>
        </div>
    )
}

인풋이 두개라서 useState를 이용해서 상태값을 2개만들면 편하겠지만

그러면 함수도 2개만들어야 되고  아마 개발자님들은 그런 방법을 좋아하시지 않는것같다...

useState를 한번만이용하고 대신 값을 객체로 넣어서 2개의 변수를 사용할수있게 해준다.

useState로 변수를 만들때 inputs에 name : " " , nickname : " " 프로퍼티 들이 들어가고

이 프로퍼티들을 객체 구조분해 할당으로 {name,nickname} 변수에 담아준것이다 

그리고 인풋에 값을 입력해서 change함수가 실행되면 실행한 인풋태그의 name과 value 값을 가져와서 변수로 저장하고

setInputs() 을 실행시키는데 ...inputs(스프레드구문) 으로 inputs안에 있는

객체를 펼쳐서 넣어주고(원래있던값을저장)

새롭게  name변수 (닉네임인풋을 실행시키면 nickname이 들어가고

네임 인풋으로 실행되면 name이 들어감) 키에 밸류로 입력한 값이 들어가게된다. 

 

최대한 풀어서 설명하긴했는데 천천히 읽다보면 아마 이해가되지않을까 ? 혹시 이해가안되는 점이있다면 댓글로달아주시면 제가 이해한부분에대해서는 설명해드리겠습니다. 저도모른다면 죄송합니다....

저는 벨로퍼트라는 분의 예제를 보고 따라하면서 공부하고 있으니 더 자세한 정보가 필요하시다면 구글에 vlpt검색하고 들어가시면 더 좋은 자료 찾으실수있을거에여 열공합시다~

반응형
반응형

조건부 렌더링이란 특정조건에따 다른결과물을 렌더링해주는것이다.

 

App.js 에서Hello 컴포넌트를 사용할때 Props로 isSpecial={true}를 전송해준다

true는 자바스크립트의 불린이기 때문에 중괄호로 감싸줘야한다. 

function App() {
  return (
    <div className="App">
      <Wrapper>
        <Hello name="ME" color="turquoise" isSpecial={true}/>
        <Hello color="pink"/>
      </Wrapper>
    </div>
  );
}

 

 

function Hello({color,name,isSpecial}){
    return(
            <div style={{color}}>
                {isSpecial ? <b>*</b>: null}
                안녕하세요 {name}
            </div>
        )
}
Hello.defaultProps = {
    name:"이름없음",
}

Props로 isSpecial을 받아서 삼항연산자로 true이면 <b>*</b> false이면 null을 출력한다.

JSX에서 Null,undefined,false를 렌더링하면 아무것도 나타나지않는다.

 

function Hello({color,name,isSpecial}){
    return(
            <div style={{color}}>
                {isSpecial && <b>*</b>}
                안녕하세요 {name}
            </div>
        )
}
Hello.defaultProps = {
    name:"이름없음",
}

삼항연산자 대신 && 형태로도 사용이가능하다 isSpecial 이 true 이면 <b>*</b>을 출력하고 그렇지않다면 false를 출력해준다. 단순한 조건문일때는 이렇게 줄여서 쓰는 쪽이좋고 조금 복잡한 조건을 줄때는 삼항연산자를 사용해서 조건을 주는게 좋아보인다.

 

props 값을 설정하게 될 때 만약 props 이름만 작성하고 값 설정을 생략한다면, 이를 true 로 설정한것으로 된다

function App() {
  return (
    <div className="App">
      <Wrapper>
        <Hello name="ME" color="turquoise" isSpecial/>
        <Hello color="pink"/>
      </Wrapper>
    </div>
  );
}

이렇게 isSpecial 을 만들고 값을 넣지않아도 똑같이 출력이된다 isSpecial = {true} 랑 같음

 

 

상태관리(State)

이번에는 useState 라는 함수를 사용해보게 되는데, 이게 바로 리액트의 Hooks 중 하나입니다. (라고 하시네요..)

들은 얘기로는 원래는 클래스형컴포넌트? 에서만 쓸수있었는데 16버전부터인가 함수형도 쓸수있게 되었다고 한다.

 

우선 상태관리 예제를 만들자..

Counter.js

import React from 'react'

function Counter(){
    return (
        <div>
            <h1>0</h1>
            <button>+1</button>
            <button>-1</button>
        </div>
    )
}

export default Counter

 

Counter 컴포넌트를 App.js에 넣어서 렌더링 해준다

App.js

import Counter from './components/Counter';

function App() {
  return (
      <Counter/>
    );
}

export default App;

 

이제 카운터에서 버튼을 클릭했을때 숫자값이 변하게되는 이벤트를 걸어주면 된다.

import React from 'react'

function Counter(){
    const onIncrease = ()=>{
        console.log('+1')
    }
    const onDecrease = ()=>{
        console.log('-1')
    }
    return (
        <div>
            <h1>0</h1>
            <button onClick={onIncrease}>+1</button>
            <button onClick={onDecrease}>-1</button>
        </div>
    )
}

export default Counter

함수를 두개 만들어주고  태그에 클릭이벤트가 발생할때 함수가실행되도록 걸어줬다.

콘솔로그를 했으니 콘솔에는 잘출력되었지만 이 함수로는 저 0값을 바꿀수없다,...그리고 더하기를 해줘서 값을

변경시킨다고 해도 바로 반영되지않는다. 여기서 이제 State가 필요한것이다.

 

컴포넌트에서 동적인 값을 상태(state)라고 부릅니다. 리액트에 useState 라는 함수가 있는데요, 이것을 사용하면 컴포넌트에서 상태를 관리 할 수 있습니다.(라고 선생님께서는 말씀하셨지,,)

import React,{useState} from 'react'

React를 임포트한줄에서 useState도 임포트 해준다 . 그러면 이제 useState를 사용할수있다

 

Counter.js

import React,{useState} from 'react'

function Counter(){
    const [number,setnumber] = useState(0)
    const onIncrease = ()=>{
        setnumber(number+1)
    }
    const onDecrease = ()=>{
        setnumber(number-1)
    }
    return (
        <div>
            <h1>{number}</h1>
            <button onClick={onIncrease}>+1</button>
            <button onClick={onDecrease}>-1</button>
        </div>
    )
}

export default Counter

갑자기 코드에서 처음본게 생겨서 많이 당황스러울텐데 설명을 해보자면

 useState함수를 사용하면 초기값과 초기값을 변경할수있는 배열을 리턴해준다 위 코드의 경우에는

useState(0) 으로 초기값을 0으로 설정해서

number변수에 저장했고 이 값을 변경할수있는 함수를 setnumber에 저장한것이다.

그리고 함수가 실행될때 setnumber를 이용해서 number값을 변경시켜주고 

숫자 0이있던 위치에 number변수를 넣어준것이다.

그럼 이제 클릭할때마다 state인 number값이 변하게되고 state가 변경되면 리액트 페이지에서 DOM을 비교해서 바뀐값을 바로바로 반영해주게되는것이다.

 

함수형 업데이트

지금은 Setter 함수를 사용 할 때, 업데이트 하고 싶은 새로운 값을 파라미터로 넣어주고 있는데요, 그 대신에 기존 값을 어떻게 업데이트 할 지에 대한 함수를 등록하는 방식으로도 값을 업데이트 할 수 있습니다.

Counter 컴포넌트를 다음과 같이 수정해보세요.

import React,{useState} from 'react'

function Counter(){
    const [number,setnumber] = useState(0)
    const onIncrease = ()=>{
        setnumber(prevNumber=>prevNumber+1)
    }
    const onDecrease = ()=>{
        setnumber(prevNumber=>prevNumber-1)
    }
    return (
        <div>
            <h1>{number}</h1>
            <button onClick={onIncrease}>+1</button>
            <button onClick={onDecrease}>-1</button>
        </div>
    )
}

export default Counter

값을 업데이트 하는 함수를 파라미터로 넣어주었습니다.

함수형 업데이트는 주로 나중에 컴포넌트를 최적화를 하게 될 때 사용하게 됩니다. 지금 당장은 함수형 업데이트란게 있는 것 정도만 이해해두시면 충분합니다. 이게 왜 최적화랑 관련이 되어있는지는 나중에 알아보도록 할게요.(라고 하십니다 선생님 너무 어려워요,,,ㅜㅠㅠㅠ)

 

일단 상태를 변경하는 방법까지는 끝!! 거의다 이해가되는것같다.

반응형
반응형

저번에 만들었던 파일에서 부터 이어서 시작~

 

저번에 썻던 Hello컴포넌트에 props를이용해서 값을 전달해줄것이다.

Hello컴포넌트를 import 하고있는 App.js에서 키값을name으로 하고 값을 전달해준다

키값과 밸류값형태로 전달된다.

이제 값을 보내줬으니 Hello 컴포넌트에서 값을 받아서 넣어주면된다

Hello 컴포넌트에서 파라미터에 변수를넣고 변수.키 를넣어주면 App에서 보내준 value를 받을수있다.

변수의 이름은 아무거나 써도 상관없지만 남들이 다 props라고 쓰는 이유가 있을테니 나는 그냥 쓰겠다.

쓰던거에 계속 덕지덕지 붙이다보니 보기에 좋지는 않지만

어쨋든 props로 전달된값이 잘 출력되는걸 확인할수있다.

 

이번에는 app.js 에서 color 키에 색을 담아서 보내주고 Hello.js에서 받아서 style에 추가해주는 예제이다

function App() {
  return (
    <div className="App">
      <Hello name="it's Me" color="yellow"/>
    </div>
  );
}
function Hello(props){
    const leave = `전 이 세상의 모든 굴레와 속박을 벗어 던지고 
                 제 행복을 찾아 떠납니다! 여러분도 행복하세요오오!!!`
    const style = {
        backgroundColor:'Red',
        fontSize:24,  // px이 기본단위
        color:'white'
    }
    return(
        <>
            <div className='Hello' style={{color: props.color}}>{props.name}안녕하세요 여러분</div>
            <div style={style}>{props.name}안녕히계세요 여러분</div>
            {leave}
        </>
    )
}

props로 보내준 color를 받아서 사용할수있다.

 

props로 보내준값을 객체구조분해 할당으로 받아서 앞에 props. 을 붙이지않고 이용하는것도 가능하다.

function Hello({color,name}){
    const leave = `전 이 세상의 모든 굴레와 속박을 벗어 던지고 
                 제 행복을 찾아 떠납니다! 여러분도 행복하세요오오!!!`
    const style = {
        backgroundColor:'Red',
        fontSize:24,  // px이 기본단위
        color:'white'
    }
    return(
        <>
            <div className='Hello' style={{color: color}}>{name}안녕하세요 여러분</div>
            <div style={style}>{name}안녕히계세요 여러분</div>
            {leave}
        </>
    )
}

키값인 color와 name을 변수명으로 설정해서 객체 구조분해할당으로 props를 받아왔다.

결과화면은 이전과 똑같이 나온다.(예쁜화면은 아니라서 두번은 안쓸게요..)

 

propsdefault 값

props를 보내주지 않을때에도 props를 사용하려면

props를 사용하는 컴포넌트에서 defaultProps를 설정하면된다.

function Hello({color,name}){
    const leave = `전 이 세상의 모든 굴레와 속박을 벗어 던지고 
                 제 행복을 찾아 떠납니다! 여러분도 행복하세요오오!!!`
    const style = {
        backgroundColor:'Red',
        fontSize:24,  // px이 기본단위
        color:'white'
    }
    return(
        <>
            <div className='Hello' style={{color: color}}>{name}안녕하세요 여러분</div>
            <div style={style}>{name}안녕히계세요 여러분</div>
            {leave}
        </>
    )
}
Hello.defaultProps = {
    name:"이름없음",
    color:"tomato"
}

App.js에서 보내주는 값을 지우면 디폴트로 되있던  props값들이 적용된다.

 

 

컴포넌트사이에 있는 값을 조회하고싶을때에는 props.children을 사용하면 조회가 가능하다

 

props.children을 사용하기위해 새로 컴포넌트를 만들었다.

import React from 'react'
function Wrapper(){
    const style ={
        border: "2px solid black",
        padding:"16px",
    };
    return(
        <div style={style}>

        </div>
    )
}
export default Wrapper

그리고 이걸 app.js에서 사용해서 Hello컴포넌트를 감싸준다.

function App() {
  return (
    <div className="App">
      <Wrapper>
        <Hello name="ME" color="turquise"/>
        <Hello color="pink"/>
      </Wrapper>
    </div>
  );
}

이렇게 사용하고 화면을 확인해보면  Hello컴포넌트부분이 안보이게된다.

출력이미지

그래서  props.children으로 Wrapper 컴포넌트안에있는 Hello컴포넌트를 받아서 다시 렌더링해줘야한다

function Wrapper({children}){
    const style ={
        border: "2px solid black",
        padding:"16px",
    };
    return(
        <div style={style}>
            {children}
        </div>
    )
}

태그사이의 요소는children이라는 키로 저장되기때문에

children으로 구조분해할당으로 받아서 변수를 사용한것이다.

이렇게 해주면 Wrapper컴포넌트 안의 안보이던 Hello 컴포넌트가 보이게된다.

 

반응형
반응형

리액트 예제풀기 시작!

 

우선 저번 포스팅에 설명한것처럼 폴더를 만들고 비쥬얼스튜디오로 폴더를 열면 

안에 요렇게 파일들이 있다. 어떤파일들인지는 나도 아직은 잘...

저기서 예제를 풀떄 사용할 폴더는 src폴더이다. 

src 폴더 안의 app.js를 열어준다

이렇게 코드들이 쓰여있는데 저번 포스팅에서본 react화면을 구성하는 코드들이다

우리는 그화면에 다른걸 띄울예정이니 <div className="App">안쪽 코드는 지워버리자~

새로운 컴포넌트를 넣을 div를 남겨놓고 나머지 내부에있던 태그들을 전부 지웠다.

컴포넌트를 만들고 export 해준뒤에 app.js파일에서 import해서 사용할예정이다.

 

src폴더안에 여러 컴포넌트들을 만들어서 관리할 components폴더를 만들어주자

그리고 그 안에 대망의 첫번째 예제인  Hello.js를 만들어준다. 

<!**** 컴포넌트의 이름의 첫글자는 무조건 대문자로 해야한다  hello.js 면 에러남>

 

Hello.js에

컴포넌트를 작성해준다.

import React from 'react'

function Hello(){
    return(
        <div>안녕하세요</div>
    )
}

export default Hello;

 

리액트 컴포넌트를 만들때에는 반드시 React 를 불러와 주어야한다.

import React from 'react'

이제 이 컴포넌트를 app.js 에서 임포트해서 사용하면된다.

위 그림 처럼 Hello를 저 경로에서 import해주고 태그안에 Hello 컴포넌트를 넣어주면 사용할수있다.

app.js의 저 그림윗줄에 import되어있는 css와 svg는 지금 쓰지않으니 지워줘도 되고 놔둬도 상관없다.

 

실행하게되면 이런 이미지가 나오게된다.

(css를 지우지않았다면 textalign이 되어있어서 글자가 가운데에있을것이다.)

혹시 화면띄우는 법을모른다면 터미널에서 npm start를 해주면 loclahost:3000에 호스팅되고 자동으로 윈도우가 열린다.

실수로 화면을 닫았다면 주소창에 localhost:3000을 치고 들어가면 된다.

 

이렇게 컴포넌트를 만들어서 사용하는 이유는 재사용하기쉽고 유지보수하기에도 유리하기때문이다 

예를 들어 똑같은 파일 여러개로 페이지를 만들었다면 수정사항이 있을때 같은파일들의 같은부분을

전부 수정해주어야하지만

이렇게 모듈식으로 쓰게되면 이 모듈 하나만 수정하면 전체에 반영되는 장점이 있다.

(라고는 하는데 아직은 모르겠다.)

import Hello from './components/Hello';
function App() {
  return (
    <div className="App">
      <Hello />
      <Hello />
      <Hello />
    </div>
  );
}
export default App;

 

이렇게 같은모듈을 여러번 사용할수있고 컴포넌트인 Hello.js의 내용하나만 수정하면 전부 바뀌게된다.,

Hello.js의 안녕하세요를 한녕하세요 여러분으로 바꿔주었다.

 

그리고  app.js 파일을보면 App도 export해주는데 App을 사용하는곳은 index.js 이고 여기서는 컴포넌트를 렌더링해서 root에 넣어주게 된다 root는 public 의 index.html폴더에있다.

 

 

React 에서는 JSX라는 문법을 쓰는데

function App() {
  return (
    <div className="App">
      <Hello />
      <Hello />
      <Hello />
    </div>
  );
}

저기 return의 안쪽부분이다 HTML과 비슷하지만 자바스크립트이다.

저 안쪽에서 XML형태로 코드를 작성하면 babel이 코드를 자바스크립트로 변경해준다.

 

 

Babel · The compiler for next generation JavaScript

The compiler for next generation JavaScript

babeljs.io

 

JSX를 작성할때 주의점 

1.태그를 꼭 닫아준다

한개짜리 태그여도 셀프클로징으로 닫아줘야 에러가 나지않는다.

<div> </div>
<input / >
<br / >

2.태그는 하나로 감싸져있어야한다

function Hello(){
    return(
        <div>안녕하세요 여러분</div>
        <div>안녕히계세요 여러분</div>
    )
}

이렇게 쓰면 에러가난다...(눈물)

function Hello(){
    return(
        <div>
            <div>안녕하세요 여러분</div>
            <div>안녕히계세요 여러분</div>
        </div>
    )
}

이렇게 하나의 태그로 감싸져 있어야 여러개의 태그를 사용할수있다.

function Hello(){
    return(
        <>
            <div>안녕하세요 여러분</div>
            <div>안녕히계세요 여러분</div>
        </>
    )
}

또는 이렇게  fragment라는 걸 사용해서도 만들수있는데 fragment를 사용해서 만들면 나중에 마크업이 되었을때 fragment태그는 제외하고 나타난다.

 

JSX내부에서 자바스크립트 변수를 사용하거나 자바스크립트구문을 사용하려면 { }를 써서 사용해야한다

style

 

JSX 에서 태그에 style을 설정하는 방법은 인라인 스타일은 객체 형태로 만들고, background-color 처럼 - 로 구분되어 있는 이름들은 backgroundColor 처럼 camelCase 형태로 네이밍 해주어야 합니다.

function Hello(){
    const leave = `전 이 세상의 모든 굴레와 속박을 벗어 던지고 
                 제 행복을 찾아 떠납니다! 여러분도 행복하세요오오!!!`
    const style = {
        backgroundColor:'Red',
        fontSize:24,  // px이 기본단위
        color:'white'
    }
    return(
        <>
            <div>안녕하세요 여러분</div>
            <div style={style}>안녕히계세요 여러분</div>
            {leave}
        </>
    )
}

스타일 을 객체로 작성해주고 태그안에 변수로 넣어주면 css가 적용된다

css 지옥편

class 설정

JSX에서 클래스를 설정할때는 class=" " 이 아니라 className=" " 으로 설정한다

function Hello(){
    const leave = `전 이 세상의 모든 굴레와 속박을 벗어 던지고 
                 제 행복을 찾아 떠납니다! 여러분도 행복하세요오오!!!`
    const style = {
        backgroundColor:'Red',
        fontSize:24,  // px이 기본단위
        color:'white'
    }
    return(
        <>
            <div className='Hello'>안녕하세요 여러분</div>
            <div style={style}>안녕히계세요 여러분</div>
            {leave}
        </>
    )
}

class에 Hello가 적용되었다. css파일을 만들고 Hello.js파일에 임포트 시켜서 클래스를 이용해서 스타일을 줄수도있다.

 

 

리액트 포스팅은 학원수업과 벨로퍼트 포스팅을 보고 따라만든것입니다. 

https://react.vlpt.us/ 여기가 리액트 맛집입니다

반응형
반응형

사용자 인터페이스를 만들기 위한 자바스크립트 라이브러리 종류

리액트 , 뷰 , 앵귤러 //

 

리액트란 ) 

실제 dom과 가상의dom을 비교해서 가상의 돔의 상태가 

변경되면 실제의dom을 변경시켜준다

**하나의 태그 , 닫기 필수 

 

리액트의 장점

  • 컴포넌트 단위 개발(생산성 향상,유지보수 용이)
  • 싱글페이지 어플리케이션 (사용자 경험 개선)
  • 높은 인지도(vue가 난이도는 더 낮지만 react가 사용자가 가장많음)

 

jsx 구문 (리액트에서 사용하는 xml을 자바스크립트로바꿔주는 구문)

  • 닫혀야 하는 태그(태그는 꼭 닫혀야 합니다.)
  • 하나의 태그로 감싸져 있어야 함. (< ></ >)
  • jsx안에 자바스크립트 사용은 { }감싼다.
  • class 지정은 classname속성을 사용
  • 주석 { /* 주석 */ }

리액트설치법)

1.Node.js를 설치해준다 (검색하고 들어가서 다운받으면됨..)

2.cmd 를 켠다 리액트파일을만들어줄 폴더를 생성하고 cmd 위치를 해당폴더로 이동

            cd C:\Users\me\Desktop\react(리액트파일을 만들어줄폴더이름)

            npx create-react-app 폴더이름

 

그러면 어려운 영어들이 실행되면서 리액트 폴더를 만들어준다.

 

Happy hacking! 이 뜨면 성공이다.

성공하면 이제 비쥬얼스튜디오로 해당폴더위치에 들어가서

터미널을 켜준뒤에.(ctrl+j)

npx start를 입력해주면 localhost:3000 에 호스팅된다.

 

이런화면의 웹사이트가 켜지면 성공 이제 app.js 에 다른컴포넌트를 만들어서 임포트 시켜서 사용하면된다!

이제 예제들을 하나씩 풀어보자!~

반응형

+ Recent posts