본문 바로가기
프로그래밍/react

[220421] 리액트로 덧글기능 만들기 (CRUD 중 CR)

by 한코코 2022. 4. 26.

기초세팅

전체를 이루는 Comment

import React,{Component} from 'react'
import CommentForm from './CommentForm'
import CommentList from './CommentList'
import '../../assets/comment.css'


class Comment extends Component{
    render(){
        return(
            <ul className='comment'>
                {this.props.children}
            </ul>
        )
    }
}

export default Comment

 

입력폼을 만드는 CommentForm

import React,{Component} from 'react'

class CommentForm extends Component{
    render(){
        return(
            <li className='comment-form'>
                <form>
                    <span className="ps_box">
                        <input type="text" className='int' placeholder='댓글을 입력해주세요'/>
                    </span>
                    <input type="submit" className="btn" value="입력" />
                </form>
            </li>
        )
    }
}

export default CommentForm

 

입력결과를 출력하는 CommentList

import React,{Component} from 'react'

class CommentList extends Component{
    render(){
        return(
            <li>
                <ul className='comment-row'>
                    <li className='comment-id'>아이디</li>
                    <li className='comment-content'>제목</li>
                    <li className='comment-date'>날짜</li>
                </ul>
            </li>
        )
    }
}

export default CommentList


만들 덧글기능의 형태


children이란?

<Comment />라고 끝날 컴포넌트를 <Comment></Comment>로 만들어서 그 사이에 넣는 컴포넌트를 children이라고 한다.

아래코드를 보면 CommentForm과 CommentList가 Comment 컴포넌트 사이에 있다.

즉, Comment 컴포넌트의 children은 CommentForm과 CommentList이다.

class App extends Component{
    state={
        value:'hellllloooooo'
    }

    render(){
        return(
            <>
                {/* <Comment /> */}
                <Comment value={this.state.value}>
                    {/* 여기가 children이 들어가는 공간 */}
                    <CommentForm />
                    <CommentList />
                </Comment>
            </>
        )
    }
}

 

children과 state

CommentList에서 state를 만들었다면 뿌리기는 엄청 쉽다. 내부적으로 처리가 가능하니까.

CommentForm도 같이 처리할 경우를 생각해보자.
CommentForm과 commentList는 서로 부모관계가 아니므로 state를 전달해줄 수 없다.
그래서 두 컴포넌트의 부모인 Comment에서 state를 다룸으로써 state를 전달할 수 있다.
 
하지만 지금은 children을 사용해서 진행중이니까, 제일 부모급인 App에서 state를 다뤄보자.
class App extends Component{
    state={
        value:'hellllo',
        list:[
            {userid:'ingoo7022',content:'안녕하세요',date:'2022-04-21'},
        ]
    }

    render(){
        const {list} = this.state
        return(
            <>
                <Comment>
                    {/* 여기가 children이 들어가는 공간 */}
                    <CommentForm />
                    <CommentList list={list}/>
                </Comment>
            </>
        )
    }
}

 


CRUD 중 R 만들기

App에 임의의 값을 넣고 CommentList에서 전달받은 값을 출력하기

//CommentList.jsx
import React,{Component} from 'react'

class CommentList extends Component{
    items = this.props.list.map((v,k)=>{
        return(
            <ul className='comment-row'>
                <li className='comment-id'>{v.userid}</li>
                <li className='comment-content'>{v.content}</li>
                <li className='comment-date'>{v.date}</li>
            </ul>
        )
    })

    render(){
        return(
            <li>
                {this.items}   
            </li>
        )
    }
}

export default CommentList

 

 

 

 

생명주기함수 componentDidMount()

class App extends Component{
    state={
        value:'hellllo',
        list:[
            {userid:'ingoo7022',content:'안녕하세요',date:'2022-04-21'},
        ]
    }

    //생명주기 함수 중 가장 자주쓰이는 두가지
    componentDidMount(){
        console.log('헿헿')
        //상태를 바꿈 -> render() 재실행
        this.setState({
            ...this.state,
            list:[{userid:'ingoo7022',content:'안녕하세요2222',date:'2022-04-21'},]
        })
    }
    render(){
        const {list} = this.state
        console.log('hello app component')
        return(
            <>
            {gogo()}
                <Comment>
                    {/* 여기가 children이 들어가는 공간 */}
                    <CommentForm />
                    <CommentList list={list}/>
                </Comment>
            </>
        )
    }
}
function gogo(){
    console.log('gogo')
}
export default App;


/*
출력값
hello app component
gogo
헿헿
hello app component
gogo
*/

 

여기서 조금더 나아가면 백그라운드로 보낼 수 있다.

// aa=async () => {
//     axios.post('http://localhost:4001',body).then(v=>{
//         this.setState({})
//     }) axios로만 만들때
// }

//생명주기 함수 중 가장 자주쓰이는 두가지
componentDidMount(){ //최초실행
    console.log('헿헿')
    //상태를 바꿈 -> render() 재실행
    this.setState({
        ...this.state,
        list:[{userid:'ingoo7022',content:'안녕하세요2222',date:'2022-04-21'},]
    })

    // axios.post('http://localhost:4001',body).then(v=>{
    //     this.setState({})
    // }) axios로만 만들때

    //this.aa() //await을 사용할때
}

 

 

 

 

Client Side Rendering (CRS)

1.   홈페이지에 접속했을때

프론트 서버에서 홈화면을 다 가져온다. (화면을 구성하는데 필요한 데이터 모두!)

 

2.   게시판 버튼을 클릭했을때

게사판 컴포넌트가 활성화 됨

componentDidMount()실행됨.

백엔드에 요청 게시판을 그리기 위한 데이터요청을 보냄.

 

3.   다시 홈페이지버튼을 눌렀을때

이미 렌더가 되었던 페이지기때문에 최초에만 실행되는 componentDidMount()는 실행되지 않음

정보는 이미 최신화되어있음.

 

 


CRUD 중 C 만들기

CommentFrom.jsx

import React, { Component } from 'react'
import Comment from './components/comment/Comment'
import CommentForm from './components/comment/CommentForm'
import CommentList from './components/comment/CommentList'

class App extends Component{
    state={
        value:'hellllo',
        list:[]
    }

    componentDidMount(){
        this.setState({
            ...this.state,
            list:[
                {userid:'ingoo7022',content:'안녕하세요2222',date:'2022-04-21'},
                {userid:'ingoo7022',content:'안녕하세요2222',date:'2022-04-21'},
                {userid:'ingoo7022',content:'안녕하세요2222',date:'2022-04-21'},
            ]
        })
    }

    //content : string
    //obj
    addList = (obj) => {
        this.setState({
            list:[...this.state.list,obj]
        })
    }

    render(){
        const {list} = this.state
        return(
            <>
                <Comment>
                    <CommentForm addList={this.addList}/>
                    <CommentList list={list}/>
                </Comment>
            </>
        )
    }
}

export default App;

 

CommentForm.jsx

import React,{Component} from 'react'

class CommentForm extends Component{
    state={
        value:''
    }

    handleChange = e => {
        // console.log('hello ') 입력확인용
        const {value} = {...e.target}
        this.setState({
            value
        })
    }

    handleSubmit = e=> {
        e.preventDefault()
        console.log(this.state.value)
        //axios 결과물을 줄때, 그때 상태를 주면 됨
        //then 콜백함수 안에서 상태를 바꾸면 됨
        //await쓸거면 await 이후에 생각하면 됨.
        const obj={userid:'ingoo7022',content:this.state.value,date:'2022-04-21'}

        //submit버튼을 눌렀을때 input박스에 있는 내용을 가져오기
        //App 컴포넌트에 있는 list 값을 push 해줘야함
            //App 컴포넌트에서 상태를 바꿀 수 있는 함수 생성
            //App 컴포넌트에서 상태를 바꿀 수 있는 함수를, CommentForm 컴포넌트에게 props로 전달
            //handleSubmit 함수가 호출되었을때 props로 전달받은 함수 실행
            
            //props로 전달받은 함수는 CommentFrom에서 받은 상태 value값을 인자값으로 넣어준다
            //CommentForm에 있는 value라는 상태값을 '' 빈 문자열로 상태를 바꾼다.
            this.props.addList(obj)
            this.setState({
                value:'' //입력한후 input창 빈칸
            })
    }

    render(){
        return(
            <li className='comment-form'>
                <form onSubmit={this.handleSubmit}>
                    <span className='ps_box'>
                        <input
                            type="text"
                            className='int'
                            placeholder='댓글을 입력해주세요'
                            onChange={this.handleChange}
                            value={this.state.value}
                        />
                    </span>
                    <input type="submit" className="btn" value="입력" />
                </form>
            </li>
        )
    }
}

export default CommentForm

 

댓글