오늘 배울 내용의 코드 기초버전
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>
'블록체인 기반 핀테크 및 응용 SW개발자 양성과정 일기' 카테고리의 다른 글
[78일차] 20210702 React 리액트 함수형 컴포넌트 (0) | 2021.07.02 |
---|---|
[76-77일차 복습] 리액트 댓글 추가 수정 삭제 / React 합성과 상속 (0) | 2021.07.01 |
[76일차] 20210630 React 리액트 push, children (0) | 2021.06.30 |
[75일차 복습] React, state 끌어 올리기 / 리액트 구구단 (0) | 2021.06.29 |
[75일차] 20210629 React 리액트 구구단 출력하기 (0) | 2021.06.29 |