본문 바로가기

블록체인 기반 핀테크 및 응용 SW개발자 양성과정 일기

[77일차]20210701 React 댓글 수정 삭제 / 리액트로 생각하기 / 합성과 상속

반응형

 

오늘 배울 내용의 코드 기초버전 

https://github.com/ingoo-code/comments/blob/master/src/index.js

 

 

 

댓글의 수정 삭제 

Comment라는 Component를 만들어 놓으면 이리저리 사용이 용이 ! 

 

 

 

1.  Comment Component 를 return하는  App Component 기본 코드 

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>리액트 시간</title>
    <script crossorigin src="https://unpkg.com/react@17/umd/react.development.js"></script>
    <script crossorigin src="https://unpkg.com/react-dom@17/umd/react-dom.development.js"></script>
    <script src="https://unpkg.com/@babel/standalone/babel.min.js"></script>
    <link rel="stylesheet" href="./example6.css">
</head>

<body>

    <div id="root"></div>
    <script type="text/babel">

        class CommentLayout extends React.Component{
            render(){
                return(

                )
            }
        }

        class Comment extends React.Component{
            render(){
                return(
                    
                )
            }
        }

        class App extends React.Component{
            render(){
                return(
                    <Comment />
                )
            }
        }

        ReactDOM.render(
            <App/>,
            document.querySelector('#root')
        )
    </script>
</body>

</html>

 Comment 는 모든 댓글 기능이 다 그려진 역할 

App은 다른 기능들도 있는 전체 wrap(?)같은 존재 

 

2. Comment에는 CommentForm / CommentList를 return하는 CommentLayout을 return

+ CommentForm / CommentList 기본 코드 입력 

        class CommentForm extends React.Component{
            render(){
                return(

                )
            }
        }

        class CommentList extends React.Component{
            render(){
                return(

                )
            }
        }

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

        class Comment extends React.Component{
            render(){
                return(
                    <CommentLayout>
                        <CommentForm />
                        <CommentList />
                    </CommentLayout>
                )
            }
        }

        class App extends React.Component{
            render(){
                return(
                    <Comment />
                )
            }
        }

 

 

 

3. html 채우기 

* CommentLayout은 기능은 딱히 없고 그냥 틀 ! 

        class CommentForm extends React.Component{
            render(){
                return(
                    <li className="comment-form">
                        <form>
                            <h4>댓글쓰기 <span>(3)</span></h4>
                            <span className="ps_box">
                                <input type="text" placeholder="댓글내용을 입력해주세요." className="int" />
                            </span>
                            <input type="submit" value="등록" className="btn" />
                        </form>
                    </li>
                )
            }
        }

        class CommentList extends React.Component{
            render(){
                return(
                    <>
                        <li>
                            <ul className="comment-row">
                                <li className="comment-id">web7722</li>
                                <li className="comment-content">안녕하세요 방가</li>
                                <li className="comment-date">20221-06-28</li>
                            </ul>
                        </li>
                        <li>
                            <ul className="comment-row">
                                <li className="comment-id">web7722</li>
                                <li className="comment-content">안녕하세요 방가</li>
                                <li className="comment-date">20221-06-28</li>
                            </ul>
                        </li>
                        <li>
                            <ul className="comment-row">
                                <li className="comment-id">web7722</li>
                                <li className="comment-content">안녕하세요 방가</li>
                                <li className="comment-date">20221-06-28</li>
                            </ul>
                        </li>
                    </>
                )
            }
        }

 

 

 

4. 댓글 등록 만들기 Comment에 state : list 라는 배열 만들기

        class Comment extends React.Component{
            state={
                list:[]
            }

            onCreate = (data) =>{  //댓글 쓸 때 사용할 함수 미리 선언 
                console.log(data)
            }
            
            render(){
                return(
                    <CommentLayout>
                        <CommentForm 
                            onCreact={this.onCreate}
                        />
                        <CommentList />
                    </CommentLayout>
                )
            }
        }

 

* state는 React의 변수 이름 ! 바뀌면 안됨 

* componentDidMout() 해당 Component의 render가 완료되었을 때 실행되어짐 by React

생명 주기 중 하나 ---요거 사용위해 리스트에 넣기 --

 

 

 

5. componentDidMount() 추가 

        class Comment extends React.Component{
            state={
                list:[]
            }

            onCreate = (data) =>{  //댓글 쓸 때 사용할 함수 미리 선언 
                console.log(data)
            }

            componentDidMount(){ //생명주기 - Component가 모두 완료되었을 떄 , 화면이 그려진게 완료 되었을 때 한번 더 실행됨 
                this.setState({list:[1,2,3,4]})
            }
            
            render(){
                console.log('render')
                return(
                    <CommentLayout>
                        <CommentForm 
                            onCreact={this.onCreate}
                        />
                        <CommentList />
                    </CommentLayout>
                )
            }
        }

ComponentDidMount(){ //생명주기 - Component가 모두 완료되었을 떄 , 화면이 그려진게 완료 되었을 때 한번 더 실행됨 -> fetch로 내용json으로 받아와서 (ex.데이터통신) 넣을 때 자쥬 쓰임 

 

-> this.setState({list:[1,2,3,4]})  아래처럼 변경  (보여주기위한 예시였음) 

 

 

 

6. 두 번째 render되는 componentDidMout() 에서 list 상태 변경 후 list에 담아 CommentList에 보내기 

            componentDidMount(){ //생명주기 - Component가 모두 완료되었을 떄 , 화면이 그려진게 완료 되었을 때 한번 더 실행됨 
                let list = [
                    {userid:'emily', content:'수요일입니다', date:'2021-07-01'},
                    {userid:'emily', content:'수요일입니다', date:'2021-07-01'},
                    {userid:'emily', content:'수요일입니다', date:'2021-07-01'}
                ]
                this.setState({list})  // list:list 
            }
            
            render(){
                console.log('render')
                return(
                    <CommentLayout>
                        <CommentForm 
                            onCreact={this.onCreate}
                        />
                        <CommentList 
                            items={this.state.list}    
                        />
                    </CommentLayout>
                )
            }

 

 

 

7. CommentList 반복문을 통해 html 만들기 

        class CommentList extends React.Component {

            renderList = () => {
                return (
                    <li>
                        <ul className="comment-row">
                            <li className="comment-id">web7722</li>
                            <li className="comment-content">안녕하세요 방가</li>
                            <li className="comment-date">20221-06-28</li>
                        </ul>
                    </li>
                )
            }

            render() {
                return (
                    <>
                        {this.renderList()}
                    </>
                )
            }
        }

-> 한 줄만 나온다 

 

 

여기까지 전체 코드

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>리액트 시간</title>
    <script crossorigin src="https://unpkg.com/react@17/umd/react.development.js"></script>
    <script crossorigin src="https://unpkg.com/react-dom@17/umd/react-dom.development.js"></script>
    <script src="https://unpkg.com/@babel/standalone/babel.min.js"></script>
    <link rel="stylesheet" href="./a1.css">
</head>

<body>

    <div id="root"></div>
    <script type="text/babel">

        class CommentForm extends React.Component {
            render() {
                return (
                    <li className="comment-form">
                        <form>
                            <h4>댓글쓰기 <span>(3)</span></h4>
                            <span className="ps_box">
                                <input type="text" placeholder="댓글내용을 입력해주세요." className="int" />
                            </span>
                            <input type="submit" value="등록" className="btn" />
                        </form>
                    </li>
                )
            }
        }

        class CommentList extends React.Component {

            renderList = () => {
                return (
                    <li>
                        <ul className="comment-row">
                            <li className="comment-id">web7722</li>
                            <li className="comment-content">안녕하세요 방가</li>
                            <li className="comment-date">20221-06-28</li>
                        </ul>
                    </li>
                )
            }

            render() {
                return (
                    <>
                        {this.renderList()}
                    </>
                )
            }
        }

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

        class Comment extends React.Component {
            state = {
                list: []
            }

            onCreate = (data) => {  //댓글 쓸 때 사용할 함수 미리 선언 
                console.log(data)
            }

            componentDidMount() { //생명주기 - Component가 모두 완료되었을 떄 , 화면이 그려진게 완료 되었을 때 한번 더 실행됨 
                let list = [
                    { userid: 'emily', content: '수요일입니다', date: '2021-07-01' },
                    { userid: 'emily', content: '수요일입니다', date: '2021-07-01' },
                    { userid: 'emily', content: '수요일입니다', date: '2021-07-01' }
                ]
                this.setState({ list })  // list:list 
            }

            render() {
                console.log('render')
                return (
                    <CommentLayout>
                        <CommentForm
                            onCreact={this.onCreate}
                        />
                        <CommentList
                            items={this.state.list}
                        />
                    </CommentLayout>
                )
            }
        }

        class App extends React.Component {
            render() {
                return (
                    <Comment />
                )
            }
        }

        ReactDOM.render(
            <App />,
            document.querySelector('#root')
        )
    </script>
</body>

</html>

 

 

 

8. map 생성 

반복문에 forEach대신 map()을 쓰는 이유 ? React는 이유가 있다 ! !

forEach - 배열 반복해주지만 return 값이 없음  / 기능 없음

map - 반복해주면서 하나하나 값을 변경해줘서 반복 가능 

        class CommentList extends React.Component {

            renderList = () => {
                return (
                    this.props.items.map((item, k) => {
                        return (
                            <li key = {k}>
                                <ul className="comment-row">
                                    <li className="comment-id">{item.userid}</li>
                                    <li className="comment-content">{item.content}</li>
                                    <li className="comment-date">{item.date}</li>
                                </ul>
                            </li>
                        )
                    })

                )
            }

            render() {
                return (
                    <>
                        {this.renderList()}
                    </>
                )
            }
        }

저 (3) 을 length 로 바꾸주기 !!! 

 

 

 

 

9. input box에 내용 쓰면 위의 상위 component에서 state 바꿔서 다시 쏴주기 

- CommentForm에 state 속성 만들기 

        class CommentForm extends React.Component {
            state={           // 추가
                content:'',
            }
            render() {
                return (
                    <li className="comment-form">
                        <form>
                            <h4>댓글쓰기 <span>({this.props.count})</span></h4>
                            <span className="ps_box">
                                <input 
                                    type="text" 
                                    placeholder="댓글내용을 입력해주세요." 
                                    className="int" 
                                    name="content"   //추가
                                />
                            </span>
                            <input type="submit" value="등록" className="btn" />
                        </form>
                    </li>
                )
            }
        }

onChange 활용하기 

        class CommentForm extends React.Component {
            state={
                content:'',
            }

            handleChange=(e)=>{         // 추가 
                this.setState({state:e.target.value})
            }

            render() {
                return (
                    <li className="comment-form">
                        <form>
                            <h4>댓글쓰기 <span>({this.props.count})</span></h4>
                            <span className="ps_box">
                                <input 
                                    type="text" 
                                    placeholder="댓글내용을 입력해주세요." 
                                    className="int" 
                                    name="content"
                                    onChange={this.handleChange}    //추가
                                />
                            </span>
                            <input type="submit" value="등록" className="btn" />
                        </form>
                    </li>
                )
            }
        }

 

아래처럼 name과 state의 이름이 같으면 아래처럼 바꿀 수 있음. 그럼 handleChange라는 함수를 재사용 가능해짐 ! 

** 정말 많이 쓰는 기본

            handleChange=(e)=>{
                this.setState({[e.target.name]:e.target.value})
            }

 

 

9. 등록 버튼 클릭했을 때 내용 보내기 

* react는 링크의 이동을 허용하지않음. (불가피한 상황 제외) 

* submit 막는 preventDefault() 를 사용

            handleSubmit=(e)=>{
                e.preventDefault()  //없으면 url 이동됨
            }

            render() {
                return (
                    <li className="comment-form">
                        <form onSubmit={this.handleSubmit}>   //추가

 

 

상위 component로 값을 보내기 -> onCreate 

 

            handleSubmit=(e)=>{
                e.preventDefault()
                this.props.onCreate(this.state.content)
                this.setState({content:''})
            }

위와 아래 코드는 동일 

 

 

                            <span className="ps_box">
                                <input 
                                    type="text" 
                                    placeholder="댓글내용을 입력해주세요." 
                                    className="int" 
                                    name="content"
                                    value={this.state.content}
                                    onChange={this.handleChange}
                                />
                            </span>

value 를 꼭 넣어줘야함 ! 현재 상태값 content를 넣으면 됨 

 

 

10. 받은 data 값을 배열에 추가 

            onCreate = (data) => {  //
                let item = {userid:'dddd', content:data, date:'2021-07-04'}
                let {list} = {...this.state}
                let newList = [...list, {...item}]
                this.setState({list:newList})
            }

 

 

11. 댓글 삭제 

onDelete 함수 Comment에 생성, CommentList로 올려보내기

CommentList의 내용 content옆에 x 버튼 만들기 (span 사용) 

            onDelete=(data)=>{
                console.log(data)
            }
            componentDidMount() { //생명주기 - Component가 모두 완료되었을 떄 , 화면이 그려진게 완료 되었을 때 한번 더 실행됨 
                let list = [
                    { userid: 'emily', content: '수요일입니다', date: '2021-07-01' },
                    { userid: '하잇', content: '목요일입니다', date: '2021-07-02' },
                    { userid: '휴먼', content: '금요일입니다', date: '2021-07-03' }
                ]
                this.setState({ list })  // list:list 
            }

            render() {
                console.log('render')
                return (
                    <CommentLayout>
                        <CommentForm
                            onCreate={this.onCreate}
                            count = {this.state.list.length}
                        />
                        <CommentList
                            items={this.state.list}
                            onDelete={this.onDelete}
                        />
                    </CommentLayout>
                )
            }

 

해당 배열의 인덱스값으로 삭제 구현

 

 

 

보낼 인자값없고 이 함수의 return값없을 때 는 함수에 괄호 () 안씀 

 

* 주 의 사 항 * 
return 값 있을 때 괄호() 붙임 
인자값이 있을 때는 ()=>{}익명함수 써야함 

 

 

        class CommentList extends React.Component {

            renderList = () => {
                return (
                    this.props.items.map((item, k) => {
                        return (
                            <li key = {k}>
                                <ul className="comment-row">
                                    <li className="comment-id">{item.userid}</li>
                                    <li className="comment-content">
                                        {item.content}
                                        <span 
                                            className="comment-delete-btn" 
                                            onClick={()=>{this.props.onDelete(k)}}
                                        >
                                            x
                                        </span>
                                    </li>
                                    <li className="comment-date">{item.date}</li>
                                </ul>
                            </li>
                        )
                    })

                )
            }
            render() {
                return (
                    <>
                        {this.renderList()}   //return값 있어서 () 괄호 붙임
                    </>
                )
            }
        }

=> x를 누르면 index값이 나온다 ! 

전체코드

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>리액트 시간</title>
    <script crossorigin src="https://unpkg.com/react@17/umd/react.development.js"></script>
    <script crossorigin src="https://unpkg.com/react-dom@17/umd/react-dom.development.js"></script>
    <script src="https://unpkg.com/@babel/standalone/babel.min.js"></script>
    <link rel="stylesheet" href="./a1.css">
</head>

<body>

    <div id="root"></div>
    <script type="text/babel">

        class CommentForm extends React.Component {
            state={
                content:'',
            }

            handleChange=(e)=>{
                this.setState({[e.target.name]:e.target.value})
            }

            handleSubmit=(e)=>{
                console.log(this.props.onCreate)
                e.preventDefault()
                this.props.onCreate(this.state.content)
                this.setState({content:''})
            }

            render() {
                return (
                    <li className="comment-form">
                        <form onSubmit={this.handleSubmit}>
                            <h4>댓글쓰기 <span>({this.props.count})</span></h4>
                            <span className="ps_box">
                                <input 
                                    type="text" 
                                    placeholder="댓글내용을 입력해주세요." 
                                    className="int" 
                                    name="content"
                                    value={this.state.content}
                                    onChange={this.handleChange}
                                />
                            </span>
                            <input type="submit" value="등록" className="btn" />
                        </form>
                    </li>
                )
            }
        }

        class CommentList extends React.Component {

            renderList = () => {
                return (
                    this.props.items.map((item, k) => {
                        return (
                            <li key = {k}>
                                <ul className="comment-row">
                                    <li className="comment-id">{item.userid}</li>
                                    <li className="comment-content">
                                        {item.content}
                                        <span 
                                            className="comment-delete-btn" 
                                            onClick={()=>{this.props.onDelete(k)}}
                                        >
                                            x
                                        </span>
                                    </li>
                                    <li className="comment-date">{item.date}</li>
                                </ul>
                            </li>
                        )
                    })

                )
            }

            render() {
                return (
                    <>
                        {this.renderList()}
                    </>
                )
            }
        }

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

        class Comment extends React.Component {
            state = {
                list: []
            }

            onCreate = (data) => {  //
                let item = {userid:'dddd', content:data, date:'2021-07-04'}
                let {list} = {...this.state}
                let newList = [...list, {...item}]
                this.setState({list:newList})
            }

            onDelete=(data)=>{
                console.log(data)
                let {list} = {...this.state}
                let newList = list.filter((value, index)=>{
                    return data !== index
                })
                this.setState({list:newList})
            }


            componentDidMount() { //생명주기 - Component가 모두 완료되었을 떄 , 화면이 그려진게 완료 되었을 때 한번 더 실행됨 
                let list = [
                    { userid: 'emily', content: '수요일입니다', date: '2021-07-01' },
                    { userid: '하잇', content: '목요일입니다', date: '2021-07-02' },
                    { userid: '휴먼', content: '금요일입니다', date: '2021-07-03' }
                ]
                this.setState({ list })  // list:list 
            }

            render() {
                console.log('render')
                return (
                    <CommentLayout>
                        <CommentForm
                            onCreate={this.onCreate}
                            count = {this.state.list.length}
                        />
                        <CommentList
                            items={this.state.list}
                            onDelete={this.onDelete}
                        />
                    </CommentLayout>
                )
            }
        }

        class App extends React.Component {
            render() {
                return (
                    <Comment />
                )
            }
        }

        ReactDOM.render(
            <App />,
            document.querySelector('#root')
        )
    </script>
</body>

</html>

 

 

과제 : 내용 클릭 하면 input box로 바꾸기 & 수정 

 

어찌어찌 수정도 완료 !!

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>리액트 시간</title>
    <script crossorigin src="https://unpkg.com/react@17/umd/react.development.js"></script>
    <script crossorigin src="https://unpkg.com/react-dom@17/umd/react-dom.development.js"></script>
    <script src="https://unpkg.com/@babel/standalone/babel.min.js"></script>
    <link rel="stylesheet" href="./a1.css">
</head>

<body>
    <div id="root"></div>
    <script type="text/babel">

        class CommentForm extends React.Component {
            state = {
                content: '',
            }

            handleChange = (e) => {
                this.setState({ [e.target.name]: e.target.value })
            }

            handleSubmit = (e) => {
                console.log(this.props.onCreate)
                e.preventDefault()
                this.props.onCreate(this.state.content)
                this.setState({ content: '' })
            }

            render() {
                return (
                    <li className="comment-form">
                        <form onSubmit={this.handleSubmit}>
                            <h4>댓글쓰기 <span>({this.props.count})</span></h4>
                            <span className="ps_box">
                                <input
                                    type="text"
                                    placeholder="댓글내용을 입력해주세요."
                                    className="int"
                                    name="content"
                                    value={this.state.content}
                                    onChange={this.handleChange}
                                />
                            </span>
                            <input type="submit" value="등록" className="btn" />
                        </form>
                    </li>
                )
            }
        }

        class CommentList extends React.Component {
            renderList = () => {
                return (
                    this.props.items.map((item, k) => {
                        return (
                            <li key={k}>
                                <ul className="comment-row">
                                    <li className="comment-id">{item.userid}</li>
                                    <li
                                        className="comment-content"
                                        onClick={() => { this.props.inputChange(k) }}
                                        //onMouseOut={() => this.props.inputMouseOut(k)}
                                        onChange={() => { this.props.onChange(k) }}
                                        value={item.content}
                                    >
                                        {item.content}
                                        <span
                                            className="comment-delete-btn"
                                            onClick={() => { this.props.onDelete(k) }}
                                        >
                                            x
                                        </span>
                                    </li>
                                    <li className="comment-date">{item.date}</li>
                                </ul>
                            </li>
                        )
                    })

                )
            }

            render() {
                return (
                    <>
                        {this.renderList()}
                    </>
                )
            }
        }

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

        class Comment extends React.Component {
            state = {
                list: [],
            }
            REF = React.createRef();

            onCreate = (data) => {
                let item = { userid: 'dddd', content: data, date: '2021-07-04' }
                let { list } = { ...this.state }
                let newList = [...list, { ...item }]
                this.setState({ list: newList })
            }

            onDelete = (data) => {
                let { list } = { ...this.state }
                let newList = list.filter((value, index) => {
                    return data !== index
                })
                this.setState({ list: newList })
            }



            // content 클릭하면 input  box 보이게
            inputChange = (k) => {
                let { list } = { ...this.state }
                let newList = list.filter((value, index) => {
                    if (index === k) {
                        value.content = <input type="text" name="content" className="comment-update-input" defaultValue={value.content} />
                        return value
                    } else {
                        return value
                    }
                })
                this.setState({ list: newList, inputOrNot: true })
            }

            //글자 수정할 때 state 수정 -> 
            onChange = (e) => {
                let update = document.querySelector('.comment-update-input')
                let { list } = { ...this.state }
                let newList = list.filter((v, i) => {
                    if (i == e) {
                        v.content = <input type="text" name="content" className="comment-update-input" defaultValue={update.value} />
                        return v
                    } else {
                        return v;
                    }
                })
                this.setState({ list: newList })
            }

            // 클릭하면 저장 
            onModify = (e) => {
                let update = document.querySelector('.comment-update-input')
                if (e.target != update) {
                    let idx;
                    for (let i = 0; i < this.state.list.length; i++) {
                        //console.log(this.state.list[i].content.props)
                        if (this.state.list[i].content.props != undefined) {
                            idx = i
                        }
                    }

                    let { list } = { ...this.state }
                    let newList = list.filter((v, i) => {
                        if (i == idx) {
                            v.content = update.value;
                            return v;
                        } else {
                            return v;
                        }
                    })
                    this.setState({ list: newList })
                }

            }

            componentDidMount() { //생명주기 - Component가 모두 완료되었을 떄 , 화면이 그려진게 완료 되었을 때 한번 더 실행됨 
                let list = [
                    { userid: 'emily', content: '수요일입니다', date: '2021-07-01' },
                    { userid: '하잇', content: '목요일입니다', date: '2021-07-02' },
                    { userid: '휴먼', content: '금요일입니다', date: '2021-07-03' }
                ]
                this.setState({ list })  // list:list 

                let update = document.querySelector('.comment-update-input')
                document.body.addEventListener('mousedown', this.onModify)
                // if(e.target.className !=='comment-update-input'){
                //         console.log('다른곳을 찍고잇')
                // }
            }

            render() {
                return (
                    <CommentLayout>
                        <CommentForm
                            onCreate={this.onCreate}
                            count={this.state.list.length}
                        />
                        <CommentList
                            items={this.state.list}
                            onDelete={this.onDelete}
                            inputChange={this.inputChange}
                            inputMouseOut={this.inputMouseOut}
                            onModify={this.onModify}
                            //inputOrNot={this.state.inputOrNot}
                            onChange={this.onChange}
                        />
                    </CommentLayout>
                )
            }
        }

        class App extends React.Component {
            render() {
                return (
                    <Comment />
                )
            }
        }

        ReactDOM.render(
            <App />,
            document.querySelector('#root')
        )
    </script>
</body>

</html>

 

 

 

 

 

교수님의 코드 : 

1. span을 만들어서 onClick을 주기 

        class CommentList extends React.Component {

            state={
                content:'',
                key:Infinity, // 0도 값이니깐 상태 업덴 전 의미할 Infinity 넣기 
            }

            handleClick=(key)=>{
                this.setState({key})
            }

            renderList = () => {
                return (
                    this.props.items.map((item, k) => {
                        return (
                            <li key={k}>
                                <ul className="comment-row">
                                    <li className="comment-id">{item.userid}</li>
                                    <li className="comment-content">
                                        <span onClick={()=>{this.handleClick(k)}}>
                                            {item.content}
                                            {k===this.state.key ? 'input' : item.content}
                                        </span>
                                        <span
                                            className="comment-delete-btn"
                                            onClick={() => { this.props.onDelete(k) }}
                                        >
                                            x
                                        </span>
                                    </li>
                                    <li className="comment-date">{item.date}</li>
                                </ul>
                            </li>
                        )
                    })

                )
            }

 

2. inputBox 함수 추가 

        class CommentList extends React.Component {

            state={
                content:'',
                key:Infinity, // 0도 값이니깐 상태 업덴 전 의미할 Infinity 넣기 
            }

            handleClick=(key)=>{
                this.setState({key})
            }

            inputBox = (content) =>{
                return(
                    <input 
                        type="text" 
                        className="comment-update-input"
                        value={content}
                    />
                )
            }

            renderList = () => {
                return (
                    this.props.items.map((item, k) => {
                        return (
                            <li key={k}>
                                <ul className="comment-row">
                                    <li className="comment-id">{item.userid}</li>
                                    <li className="comment-content">
                                        <span onClick={()=>{this.handleClick(k)}}>
                                            {k===this.state.key ? this.inputBox(item.content) : item.content}
                                        </span>
                                        <span
                                            className="comment-delete-btn"
                                            onClick={() => { this.props.onDelete(k) }}
                                        >
                                            x
                                        </span>
                                    </li>
                                    <li className="comment-date">{item.date}</li>
                                </ul>
                            </li>
                        )
                    })

                )
            }

 

3. 

            handleEnter = (e) => {
                if(e.key=='Enter'){
                    let {key, content} = {...this.state}
                    this.props.onUpdate(key,content)
                    this.setState({key:Infinity, content:''})
                }
            }

            inputBox = (content) => {
                return (
                    <input
                        type="text"
                        className="comment-update-input"
                        defaultValue={content}
                        name="content"
                        conChange={this.handleChange}
                        onKeyDown = {this.handleEnter}
                    />
                )
            }

            renderList = () => {
                return (
                    this.props.items.map((item, k) => {
                        return (
                            <li key={k}>
                                <ul className="comment-row">
                                    <li className="comment-id">{item.userid}</li>
                                    <li className="comment-content">
                                        <span onClick={() => { this.handleClick(k) }}>
                                            {k === this.state.key ? this.inputBox(item.content) : item.content}
                                        </span>
                                        <span

-

        class Comment extends React.Component {
            state = {
                list: []
            }

            onCreate = (data) => {  //
                let item = { userid: 'dddd', content: data, date: '2021-07-04' }
                let { list } = { ...this.state }
                let newList = [...list, { ...item }]
                this.setState({ list: newList })
            }

            onDelete = (data) => {
                console.log(data)
                let { list } = { ...this.state }
                let newList = list.filter((value, index) => {
                    return data !== index
                })
                this.setState({ list: newList })
            }

            onUpdate=(index,content) =>{            //추가 
                let {list} = {...this.state}   
                list[index].content = content 
                this.setState({list})
            }

-

                        <CommentList
                            items={this.state.list}
                            onDelete={this.onDelete}
                            onUpdate={this.onUpdate}
                        />

 

 

전체 코드 

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>리액트 시간</title>
    <script crossorigin src="https://unpkg.com/react@17/umd/react.development.js"></script>
    <script crossorigin src="https://unpkg.com/react-dom@17/umd/react-dom.development.js"></script>
    <script src="https://unpkg.com/@babel/standalone/babel.min.js"></script>
    <link rel="stylesheet" href="./a1.css">
</head>

<body>

    <div id="root"></div>
    <script type="text/babel">

        class CommentForm extends React.Component {
            state = {
                content: '',
            }

            handleChange = (e) => {
                this.setState({ [e.target.name]: e.target.value })
            }

            handleSubmit = (e) => {
                console.log(this.props.onCreate)
                e.preventDefault()
                this.props.onCreate(this.state.content)
                this.setState({ content: '' })
            }

            render() {
                return (
                    <li className="comment-form">
                        <form onSubmit={this.handleSubmit}>
                            <h4>댓글쓰기 <span>({this.props.count})</span></h4>
                            <span className="ps_box">
                                <input
                                    type="text"
                                    placeholder="댓글내용을 입력해주세요."
                                    className="int"
                                    name="content"
                                    value={this.state.content}
                                    onChange={this.handleChange}
                                />
                            </span>
                            <input type="submit" value="등록" className="btn" />
                        </form>
                    </li>
                )
            }
        }

        class CommentList extends React.Component {

            state = {
                content: '',
                key: Infinity, // 0도 값이니깐 상태 업덴 전 의미할 Infinity 넣기 
            }

            handleClick = (key) => {
                this.setState({ key })
            }

            handleChange = (e) => {
                this.setState({[e.target.name]:e.target.value})
            }

            handleEnter = (e) => {
                if(e.key=='Enter'){
                    let {key, content} = {...this.state}
                    this.props.onUpdate(key,content)
                    this.setState({key:Infinity, content:''})
                }
            }

            inputBox = (content) => {
                return (
                    <input
                        type="text"
                        className="comment-update-input"
                        defaultValue={content}
                        name="content"
                        onChange={this.handleChange}
                        onKeyDown = {this.handleEnter}
                    />
                )
            }

            renderList = () => {
                return (
                    this.props.items.map((item, k) => {
                        return (
                            <li key={k}>
                                <ul className="comment-row">
                                    <li className="comment-id">{item.userid}</li>
                                    <li className="comment-content">
                                        <span onClick={() => { this.handleClick(k) }}>
                                            {k === this.state.key ? this.inputBox(item.content) : item.content}
                                        </span>
                                        <span
                                            className="comment-delete-btn"
                                            onClick={() => { this.props.onDelete(k) }}
                                        >
                                            x
                                        </span>
                                    </li>
                                    <li className="comment-date">{item.date}</li>
                                </ul>
                            </li>
                        )
                    })

                )
            }

            render() {
                return (
                    <>
                        {this.renderList()}
                    </>
                )
            }
        }

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

        class Comment extends React.Component {
            state = {
                list: []
            }

            onCreate = (data) => {  //
                let item = { userid: 'dddd', content: data, date: '2021-07-04' }
                let { list } = { ...this.state }
                let newList = [...list, { ...item }]
                this.setState({ list: newList })
            }

            onDelete = (data) => {
                console.log(data)
                let { list } = { ...this.state }
                let newList = list.filter((value, index) => {
                    return data !== index
                })
                this.setState({ list: newList })
            }

            onUpdate=(index,content) =>{
                let {list} = {...this.state}   
                list[index].content = content 
                this.setState({list})
            }

            componentDidMount() { //생명주기 - Component가 모두 완료되었을 떄 , 화면이 그려진게 완료 되었을 때 한번 더 실행됨 
                let list = [
                    { userid: 'emily', content: '수요일입니다', date: '2021-07-01' },
                    { userid: '하잇', content: '목요일입니다', date: '2021-07-02' },
                    { userid: '휴먼', content: '금요일입니다', date: '2021-07-03' }
                ]
                this.setState({ list })  // list:list 
            }

            render() {
                return (
                    <CommentLayout>
                        <CommentForm
                            onCreate={this.onCreate}
                            count={this.state.list.length}
                        />
                        <CommentList
                            items={this.state.list}
                            onDelete={this.onDelete}
                            onUpdate={this.onUpdate}
                        />
                    </CommentLayout>
                )
            }
        }

        class App extends React.Component {
            render() {
                return (
                    <Comment />
                )
            }
        }

        ReactDOM.render(
            <App />,
            document.querySelector('#root')
        )
    </script>
</body>

</html>

 

 

반응형