본문 바로가기

WINK-(Web & App)/HTML & CSS & JS 스터디

[2023 신입부원 심화 스터디] 정호용 #7주차 react - section 3 ~

반응형

📌section 3

// Section 3. State(1) - 소개


// State 는 Props 와 같이 봐야 이해가 잘 된다!
// 컴포넌트를 만드는 리액트의 관점에서는 props가 User Interface인 셈이다.
// State는 Props 값에 따라 내부 구현에 필요한 데이터 값들 이다.
// <Component props_name="props_value"
// component 내부적으로 사용되는 것들 -> State
// Props과 State가 철저히 분리 되어야 한다.
// 철저히 격리시켜서 양측의 편리함 도모



// Section 3. State(2) - 사용

class App extends Component{
    constructor(props){
        super(props);
        this.state = {
            Subject:{title:"WEB", sub:'World Wide Web!'} // State 만들기
        }
    } 
    // render함수보다 먼저 실행, component를 초기화하고 싶다면 constructor 을 쓰자
    
    render(){
        return(
            <div className="App">
                <Subject title={this.state.subject.title} 
                sub = {this.state.subject.sub}></Subject>
                // 외부에서 알 수 없게 철저히 은닉함.
                // App 이 내부적으로 사용할 상태는 State 이용함.
                // state값을 subject라는 component의 props값으로 줌.
                // 상위 componenet인 App을 하위 componenet인 props의 값으로 전달하는 것은 얼마든지 가능함.
                
                <TOC></TOC>
                <Content title="HTML" desc="HTML is HyperText Markup Language."></Content>
            </div>    
        );
    }
}

export default App;

// 위 코드를 이해하려 하기 보다는 그러려니 하고 넘어가자!


// Section 3. State(3) - key

//App.js
class App extends Component{
    constructor(props){
        super(props);
        this.state = {
            Subject:{title:"WEB", sub:'World Wide Web!'} // State 만들기
            contents:[
                {id : 1, title :'HTML', desc : "Html is for information"},
                {id : 2, title :'CSS', desc : "CSS is for design"},
                {id : 3, title :'JS', desc : "JS is for interactive"}
                
            ]
            // 데이터가 여러개이므로 대괄호로 감싸주기
        }
    } 
    // render함수보다 먼저 실행, component를 초기화하고 싶다면 constructor 을 쓰자
    
    render(){
        return(
            <div className="App">
                <Subject title={this.state.subject.title} 
                sub = {this.state.subject.sub}></Subject>
                // 외부에서 알 수 없게 철저히 은닉함.
                // App 이 내부적으로 사용할 상태는 State 이용함.
                // state값을 subject라는 component의 props값으로 줌.
                // 상위 componenet인 App을 하위 componenet인 props의 값으로 전달하는 것은 얼마든지 가능함.
                
                <TOC data = {this.state.contents}></TOC>
                <Content title="HTML" desc="HTML is HyperText Markup Language."></Content>
            </div>    
        );
    }
}

export default App;


//TOC.js

class TOC extends Component{
    render(){
        var data = this.props.data;
        var i = 0;
        while(i<data.length){
            lists.push(<li key={data[i].id}><a href={"/content/"+data[i].id}>{data[i].title}</a></li>)
            i = i+1;
        }

        // TOC의 내용이 바뀔 때 더 이상 TOC를 열지 않고 내용 수정이 가능함. 용이하다.
        // 여러 개 element를 자동으로 생성해주기 때문
        // 다만, console을 열 때 error가 발생하는데, 각각의 list 항목은 key 라는 props를 가져야 함.
        // key로 쓸 때 element들을 구별해야 함.

        return(
            <nav>
                <ul>
                    {lists}
                </ul>
            </nav>
        )
    }
}
// App 의 입장에서는 topic이 내부적으로 어떻게 돌아가는 지 알 필요 없음
// 사용자의 입장에서 알아야 할 것만 알면 된다.



📌section 4
// Section 4. Events(1) - 이벤트 state props 그리고 render 함수
// state props event가 상호작용 하며 역동성 있게 만들어줌.

//App.js

class App extends Component{
    constructor(props){
        super(props);
        this.state = {
            mode:'welcome',
            Subject:{title:"WEB", sub:'World Wide Web!'}, // State 만들기
            welcome:{title:'Welcome',desc:'Hello,React!!'},
            // react에서 state값이 바뀌면 state 값을 갖고 있는 component의 render 함수가 다시 호출됨
            // render 함수가 다시 호출됨에 따라 하위에 있는 render함수도 다시 호출됨
            // react에서는 state값이나 props가 바뀌면 해당하는 render함수가 다시 호출됨
            // 화면이 다시 그려짐.
            
            contents:[
                {id : 1, title :'HTML', desc : "Html is for information"},
                {id : 2, title :'CSS', desc : "CSS is for design"},
                {id : 3, title :'JS', desc : "JS is for interactive"}
                
            ]
        }
    } 
    
    render(){
        console.log('App render');
        var _title, _desc = null;
        if(this.state.mode === 'welcome'){
            _title = this.state.welcome.title;
            _desc = this.state.welcome.desc;
            //state의 mode가 welcome일 경우 title과 desc의 값을 바꿈.
        }else if (this.state.mode === 'read'){
            _title = this.state.contents[0].title;
            _desc = this.state.contents[0].desc;
            //state의 mode가 read일 경우 title과 desc의 값을 바꿈.
        }
        return(
            <div className="App">
                <Subject title={this.state.subject.title} 
                sub = {this.state.subject.sub}>
                </Subject>
                <TOC data = {this.state.contents}></TOC>
                <Content title={_title} desc={_desc}></Content>
            </div>    
        );
    }
}

export default App;

//subject.js

class Subject extends Component{
    render(){
        return(
            <header>
                <h1><a href="/">{this.props.title}</a></h1>
                {this.props.sub}
            </header>
        );
    }
}

export default Subject;

//content.js

class Content extends Component{
    render(){
        console.log('content render');
        return(
            <article>
                <h2>{this.props.title}</h2>
                {this.props.desc}
            </article>
        );
    }
}

export default Content;

// 호출은 App subject TOC Content순


// Section 4. Events(2) - 이벤트 설치

// App의 State를 바꾸는 것이 최종목표!

//subject.js

class Subject extends Component{
    render(){
        return(
            <header>
                <h1><a href="/">{this.props.title}</a></h1>
                {this.props.sub}
            </header>
        );
    }
}

export default Subject;


//App.js

class App extends Component{
    constructor(props){
        super(props);
        this.state = {
            mode:'welcome',
            Subject:{title:"WEB", sub:'World Wide Web!'}, // State 만들기
            welcome:{title:'Welcome',desc:'Hello,React!!'},
            // react에서 state값이 바뀌면 state 값을 갖고 있는 component의 render 함수가 다시 호출됨
            // render 함수가 다시 호출됨에 따라 하위에 있는 render함수도 다시 호출됨
            // react에서는 state값이나 props가 바뀌면 해당하는 render함수가 다시 호출됨
            // 화면이 다시 그려짐.
            
            contents:[
                {id : 1, title :'HTML', desc : "Html is for information"},
                {id : 2, title :'CSS', desc : "CSS is for design"},
                {id : 3, title :'JS', desc : "JS is for interactive"}
                
            ]
        }
    } 
    
    render(){
        console.log('App render');
        var _title, _desc = null;
        if(this.state.mode === 'welcome'){
            _title = this.state.welcome.title;
            _desc = this.state.welcome.desc;
            //state의 mode가 welcome일 경우 title과 desc의 값을 바꿈.
        }else if (this.state.mode === 'read'){
            _title = this.state.contents[0].title;
            _desc = this.state.contents[0].desc;
            //state의 mode가 read일 경우 title과 desc의 값을 바꿈.
        }
        return(
            <div className="App">
                {/* <Subject 
                title={this.state.subject.title} 
                sub = {this.state.subject.sub}>
                </Subject> */}
                <header>
                    <h1><a href="/" onClick={function(e){
                        console.log(e);
                        debugger; // debugger가 써 있는 부분에서 실행을 멈춤.
                        // e.preventDefault() : 문제가 발생한 이벤트의 태그의 실행방지
                        // -> 페이지의 reload를 방지한다. 
                    }}>{this.state.subject.title}</a></h1>
                    {this.state.subject.sub}

                </header>
                <TOC data = {this.state.contents}></TOC>
                <Content title={_title} desc={_desc}></Content>
            </div>    
        );
    }
}

export default App;



// Section 4. Events(3) - 이벤트에서 state 변경하기

//App.js

class App extends Component{
    constructor(props){
        super(props);
        this.state = {
            mode:'welcome',
            Subject:{title:"WEB", sub:'World Wide Web!'}, // State 만들기
            welcome:{title:'Welcome',desc:'Hello,React!!'},
            // react에서 state값이 바뀌면 state 값을 갖고 있는 component의 render 함수가 다시 호출됨
            // render 함수가 다시 호출됨에 따라 하위에 있는 render함수도 다시 호출됨
            // react에서는 state값이나 props가 바뀌면 해당하는 render함수가 다시 호출됨
            // 화면이 다시 그려짐.
            
            contents:[
                {id : 1, title :'HTML', desc : "Html is for information"},
                {id : 2, title :'CSS', desc : "CSS is for design"},
                {id : 3, title :'JS', desc : "JS is for interactive"}
                
            ]
        }
    } 
    
    render(){
        console.log('App render');
        var _title, _desc = null;
        if(this.state.mode === 'welcome'){
            _title = this.state.welcome.title;
            _desc = this.state.welcome.desc;
            //state의 mode가 welcome일 경우 title과 desc의 값을 바꿈.
        }else if (this.state.mode === 'read'){
            _title = this.state.contents[0].title;
            _desc = this.state.contents[0].desc;
            //state의 mode가 read일 경우 title과 desc의 값을 바꿈.
        }
        return(
            <div className="App">
                {/* <Subject 
                title={this.state.subject.title} 
                sub = {this.state.subject.sub}>
                </Subject> */}
                <header>
                    <h1><a href="/" onClick={function(e){
                        console.log(e);
                        debugger; // debugger가 써 있는 부분에서 실행을 멈춤.
                        e.preventDefault() // : 문제가 발생한 이벤트의 태그의 실행방지
                        // -> 페이지의 reload를 방지한다. 
                        // this.state.mode = 'welcome';
                        // 위 코드를 적었을 때 component를 못 찾아서 에러가 뜸.
                        // 아랫줄에 .bind(this)를 넣으면 this는 이 component에 해당하게 됨.
                        this.setState({
                            mode : 'welcome'
                        });
                        // 안 바뀜. 위의 setState를 써야 함.
                    }.bind(this)}>{this.state.subject.title}</a></h1>
                    {this.state.subject.sub}

                </header>
                <TOC data = {this.state.contents}></TOC>
                <Content title={_title} desc={_desc}></Content>
            </div>    
        );
    }
}

export default App;


// Section 4. Events(4) - bind 함수 이해하기


//App.js

class App extends Component{
    constructor(props){
        super(props);
        this.state = {
            mode:'welcome',
            Subject:{title:"WEB", sub:'World Wide Web!'}, // State 만들기
            welcome:{title:'Welcome',desc:'Hello,React!!'},
            // react에서 state값이 바뀌면 state 값을 갖고 있는 component의 render 함수가 다시 호출됨
            // render 함수가 다시 호출됨에 따라 하위에 있는 render함수도 다시 호출됨
            // react에서는 state값이나 props가 바뀌면 해당하는 render함수가 다시 호출됨
            // 화면이 다시 그려짐.
            
            contents:[
                {id : 1, title :'HTML', desc : "Html is for information"},
                {id : 2, title :'CSS', desc : "CSS is for design"},
                {id : 3, title :'JS', desc : "JS is for interactive"}
                
            ]
        }
    } 
    
    render(){

        console.log('App render');
        var _title, _desc = null;
        if(this.state.mode === 'welcome'){
            _title = this.state.welcome.title;
            _desc = this.state.welcome.desc;
            //state의 mode가 welcome일 경우 title과 desc의 값을 바꿈.
        }else if (this.state.mode === 'read'){
            _title = this.state.contents[0].title;
            _desc = this.state.contents[0].desc;
            //state의 mode가 read일 경우 title과 desc의 값을 바꿈.
        }
        console.log('render',this);
        // 여기서 this 는 자기 자신 component를 가리킴.

        return(
            <div className="App">
                {/* <Subject 
                title={this.state.subject.title} 
                sub = {this.state.subject.sub}>
                </Subject> */}
                <header>
                    <h1><a href="/" onClick={function(e){
                        console.log('event in', this);
                        return;
                        console.log(e);
                        debugger; // debugger가 써 있는 부분에서 실행을 멈춤.
                        e.preventDefault() // : 문제가 발생한 이벤트의 태그의 실행방지
                        // -> 페이지의 reload를 방지한다. 
                        // this.state.mode = 'welcome';
                        // 위 코드를 적었을 때 component를 못 찾아서 에러가 뜸.
                        // 아랫줄에 .bind(this)를 넣으면 this는 이 component에 해당하게 됨.
                        this.setState({
                            mode : 'welcome'
                        });
                        // 안 바뀜. 위의 setState를 써야 함.
                        // bind에서 this를 넘겨주면 component자체를 넘겨주는 것임.
                    }.bind(this)}>{this.state.subject.title}</a></h1>
                    {this.state.subject.sub}

                </header>
                <TOC data = {this.state.contents}></TOC>
                <Content title={_title} desc={_desc}></Content>
            </div>    
        );
    }
}

export default App;


var obj = {name : 'egoing'};
function bindTest(){
    console.log(this.name);
}
bindTest();
//-> this는 obj가 아니라 실행 안됨!
var bindTest2 = bindTest.bind(obj);
//bind함수로 인해 this는 obj가 된다.
bindTest2();





// Section 4. Events(5) - setState 함수 이해하기

//App.js

class App extends Component{
    constructor(props){
        super(props);
        this.state = {
            mode:'welcome',
            Subject:{title:"WEB", sub:'World Wide Web!'}, // State 만들기
            welcome:{title:'Welcome',desc:'Hello,React!!'},
            // react에서 state값이 바뀌면 state 값을 갖고 있는 component의 render 함수가 다시 호출됨
            // render 함수가 다시 호출됨에 따라 하위에 있는 render함수도 다시 호출됨
            // react에서는 state값이나 props가 바뀌면 해당하는 render함수가 다시 호출됨
            // 화면이 다시 그려짐.
            
            contents:[
                {id : 1, title :'HTML', desc : "Html is for information"},
                {id : 2, title :'CSS', desc : "CSS is for design"},
                {id : 3, title :'JS', desc : "JS is for interactive"}
                
            ]
        }
    } 
    
    render(){

        console.log('App render');
        var _title, _desc = null;
        if(this.state.mode === 'welcome'){
            _title = this.state.welcome.title;
            _desc = this.state.welcome.desc;
            //state의 mode가 welcome일 경우 title과 desc의 값을 바꿈.
        }else if (this.state.mode === 'read'){
            _title = this.state.contents[0].title;
            _desc = this.state.contents[0].desc;
            //state의 mode가 read일 경우 title과 desc의 값을 바꿈.
        }
        console.log('render',this);
        // 여기서 this 는 자기 자신 component를 가리킴.

        return(
            <div className="App">
                {/* <Subject 
                title={this.state.subject.title} 
                sub = {this.state.subject.sub}>
                </Subject> */}
                <header>
                    <h1><a href="/" onClick={function(e){
                        console.log('event in', this);
                        return;
                        console.log(e);
                        debugger; // debugger가 써 있는 부분에서 실행을 멈춤.
                        e.preventDefault() // : 문제가 발생한 이벤트의 태그의 실행방지
                        // -> 페이지의 reload를 방지한다. 
                        // this.state.mode = 'welcome';
                        // 위 코드를 적었을 때 component를 못 찾아서 에러가 뜸.
                        // 아랫줄에 .bind(this)를 넣으면 this는 이 component에 해당하게 됨.
                        this.setState({
                            mode : 'welcome'
                        });
                        // 안 바뀜. 위의 setState를 써야 함.
                        // bind에서 this를 넘겨주면 component자체를 넘겨주는 것임.
                    }.bind(this)}>{this.state.subject.title}</a></h1>
                    {this.state.subject.sub}

                </header>
                <TOC data = {this.state.contents}></TOC>
                <Content title={_title} desc={_desc}></Content>
            </div>    
        );
    }
}

export default App;

//this.setState 는 함수의 state가 바뀔 때 항상 setState를 써줘야 함.




📌section 5
// Section 5. Events(6) - 컴포넌트 이벤트 만들기

// return(
//     <div className="App">
//         <Subject 
//         title={this.state.subject.title} 
//         sub = {this.state.subject.sub}>
//         onChangePage={function(){
//             alert('hihihi');
//             this.setState({mode : 'welcome'});
//             // 페이지 변경 시, component의 사용자가 설치한 함수를 실행시킨다.
//         }.bind(this)};
//         </Subject>
 



//subject.js

class Subject extends Component{
    render(){
        return(
            <header>
                <h1><a href="/" onClick={function(e){
                    e.preventDefault();
                    this.props.onChangePage();
                }.bind(this)}>{this.props.title}</a></h1>
                {this.props.sub}
            </header>
        );  
        
    }
}

export default Subject;

반응형