본문 바로가기
React

[React] React hook CRUD

by Yeoseungwon 2023. 6. 18.
728x90

npm install express

npm install mysql

npm install react-router-dom

npm install axios

(XMLHttpRequest -> $.ajax -> axios)

npm install query-string

 

queryString.parse()

 

 

프로젝트

React - Express -MySQL

React : 화면 만들고, 서버에 요청(axios), 응답받고 

Express : React에서 보낸 요청을 받아들여서 인자, 쿼리스트링, 바디를 읽음 ,

                 읽고 꺼내고 가공(요청된 정보를 가공)함/ 이 연결된 데이터베이스에 CRUD

MySQL : DB구축

 

 

----------------------------------------------------------------------------------------

클래스형으로 했었던 crud 

훅으로 해보기 

 

npx create-react-app react-hook-crud

 

App.js  함수형으로 작성하고 

useState 임포트 해주기 

 

import './App.css';
import {useState} from 'react' //상태관련 훅 

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

export default App;

 

components 폴더에 InputComp.js / Person.js 파일 함수형으로 만들기

css 폴더에도 파일 만들어주기

 

App.js 데이터로 쓰일 배열 만들어주기

import './App.css';
import {useState} from 'react' //상태관련 훅 

function App() {
  const [personList, setPersonList] = useState([
    {id:1, name:'kim', age:20},
    {id:2, name:'lee', age:21},
    {id:3, name:'park', age:22}
  ])
  return (
    <div className="App">

    </div>
  );
}

export default App;

Person.js props적어주기 

훅에서는 this 를 안씀 

import '../css/Person.css'

function Person(props){
    return(
        <div id='person'>
            <div>이름 : {props.name}</div>
            <div>나이 : {props.age}</div>
            <div>키 : {props.height}</div>
        </div>
    )
}

export default Person;

 

App.js 에 map 쓰기 

훅에서는 클래스형이 아니기 때문에 render가 없음 그래서 return위에 바로 써줘야함 

result에 담고 return에 result 써주기 

 

import './App.css';
import {useState} from 'react' //상태관련 훅 
import Person from './components/Person.js';


function App() {
  const [personList, setPersonList] = useState([
    {id:1, name:'kim', age:20, height:176.6},
    {id:2, name:'lee', age:21, height:162.6},
    {id:3, name:'park', age:22, height:177.8}
  ])
  const result = personList.map(
    (data)=>(<Person name={data.name}
                    age={data.age}
                    height={data.height}/>)
  )
  return (
    <div className="App">
      {result}
    </div>
  );
}

export default App;

 

 

**실행해 보면 콘솔에 에러 메세지가 뜨는데 키값을 주지 않아서다. 

App.js 에 키값 적어주기 

  const result = personList.map(
    (data)=>(<Person key={data.id} name={data.name}
                    age={data.age}
                    height={data.height}/>)

 

InputComp.js 에 입력할 수 있는 칸 3개와 추가버튼 만들어주기

import '../css/InputComp.css'

function InputComp(props){
    return(
        <div id='input-comp'>
            <input type='text'/>
            <input type='text'/>
            <input type='text'/>
            <button>추가</button>
        </div>
    )
}

export default InputComp;

 

InputComp.js 에 함수 걸어주기  (두 가지 방법이 있음 )

import '../css/InputComp.css';
import {useState} from 'react';

function InputComp(props){
     const nameChange = (e) =>{
         console.log(e.target.value)
     }  // 검사하고 넣는방법 
    return(
        <div id='input-comp'>
            <input type='text' onChange={nameChange}/>
            <input type='text' onChange={nameChange}/>
            <input type='text' onChange={nameChange}/>
            <button>추가</button>
        </div>
    )
}

export default InputComp;

 

import '../css/InputComp.css';
import {useState} from 'react';

function InputComp(props){
    const [name, setName] = useState('') // 초기값은 없음 //검사하지 않고 넣는방법
    const [age, setAge] = useState('') // 초기값은 없음 //검사하지 않고 넣는방법
    const [height, setHeight] = useState('') // 초기값은 없음 //검사하지 않고 넣는방법
    // const nameChange = (e) =>{
    //     console.log(e.target.value)
    // }  // 검사하고 넣는방법 
    return(
        <div id='input-comp'>
            <input type='text' onChange={(e)=>setName(e.target.value)}/>
            <input type='text' onChange={(e)=>setAge(e.target.value)}/>
            <input type='text' onChange={(e)=>setHeight(e.target.value)}/>
            <button>추가</button>
        </div>
    )
}

export default InputComp;

 

이제 버튼에 클릭함수 걸어주기 

import '../css/InputComp.css';
import {useState} from 'react';

function InputComp(props){
    const [name, setName] = useState('') // 초기값은 없음 //검사하지 않고 넣는방법
    const [age, setAge] = useState('') // 초기값은 없음 //검사하지 않고 넣는방법
    const [height, setHeight] = useState('') // 초기값은 없음 //검사하지 않고 넣는방법
    // const nameChange = (e) =>{
    //     console.log(e.target.value)
    // }  // 검사하고 넣는방법 

    const addPersonInfo=()=>{
        alert('추가 !(InputComp)')
    }
    return(
        <div id='input-comp'>
            <input type='text' onChange={(e)=>setName(e.target.value)}/>
            <input type='text' onChange={(e)=>setAge(e.target.value)}/>
            <input type='text' onChange={(e)=>setHeight(e.target.value)}/>
            <button onClick={addPersonInfo}>추가</button>
        </div>
    )
}

export default InputComp;

그다음 App.js 에 넘겨받은 함수 써주고 InputComp() 매개변수에 props 써주기 

import '../css/InputComp.css';
import {useState} from 'react';

function InputComp(props){
    const [name, setName] = useState('') // 초기값은 없음 //검사하지 않고 넣는방법
    const [age, setAge] = useState('') // 초기값은 없음 //검사하지 않고 넣는방법
    const [height, setHeight] = useState('') // 초기값은 없음 //검사하지 않고 넣는방법
    // const nameChange = (e) =>{
    //     console.log(e.target.value)
    // }  // 검사하고 넣는방법 

    const addPersonInfo=()=>{
        alert('추가 !(InputComp)')
        props.addPersonInfo(name,age,height) //App한테 넘겨받은 함수 
    }
    return(
        <div id='input-comp'>
            <input type='text' onChange={(e)=>setName(e.target.value)}/>
            <input type='text' onChange={(e)=>setAge(e.target.value)}/>
            <input type='text' onChange={(e)=>setHeight(e.target.value)}/>
            <button onClick={addPersonInfo}>추가</button>
        </div>
    )
}

export default InputComp;

 

 

App.js 에도 함수 써주고 return에 주입 

import './App.css';
import {useState} from 'react' //상태관련 훅 
import Person from './components/Person.js';
import InputComp from './components/InputComp';


function App() {
  const [personList, setPersonList] = useState([
    {id:1, name:'kim', age:20, height:176.6},
    {id:2, name:'lee', age:21, height:162.6},
    {id:3, name:'park', age:22, height:177.8}
  ])
  const addPersonInfo = (name,age,height) => {
    alert('추가! (App)')
    alert(name)
    alert(age)
    alert(height)
  }


  const result = personList.map(
    (data)=>(<Person key={data.id} name={data.name}
                    age={data.age}
                    height={data.height}/>)
  )
  return (
    <div className="App">
      <InputComp addPersonInfo={addPersonInfo}/>
      {result}
    </div>
  );
}

export default App;

 

정보 넘겨받은거 확인 됐으니 

화면에 찍어낼 객체를 만들어줘야함 

concat 써주기 

(InputComp에 id 값도 변경할 수 있게 추가해줬기 때문에 id 값도 넘길 수 있게 써주기)

import './App.css';
import {useState} from 'react' //상태관련 훅 
import Person from './components/Person.js';
import InputComp from './components/InputComp';


function App() {
  const [personList, setPersonList] = useState([
    {id:1, name:'kim', age:20, height:176.6},
    {id:2, name:'lee', age:21, height:162.6},
    {id:3, name:'park', age:22, height:177.8}
  ])
  const addPersonInfo = (id,name,age,height) => {
    alert('추가! (App)')
    alert(id)
    alert(name)
    alert(age)
    alert(height)
    const personObj = {id:id, name:name, age:age,height:height}
    const concatedList = personList.concat(personObj)
    setPersonList(concatedList)
  }


  const result = personList.map(
    (data)=>(<Person key={data.id} name={data.name}
                    age={data.age}
                    height={data.height}/>)
  )
  return (
    <div className="App">
      <InputComp addPersonInfo={addPersonInfo}/>
      {result}
    </div>
  );
}

export default App;

 

 

Person.js 수정, 삭제 버튼 만들어주고 이벤트 걸기

import '../css/Person.css'

function Person(props){

    const updatePersonInfo =() =>{
        alert('수정(Person)')
    }
    const deletePersonInfo =() =>{
        alert('삭제(Person)')
        const {id} = props
        props.deletePersonInfo(id)
    }
    return(
        <div id='person'>
            <div>이름 : {props.name}</div>
            <div>나이 : {props.age}</div>
            <div>키 : {props.height}</div>
            <div>
                <button onClick={updatePersonInfo}>수정</button>
                <button onClick={deletePersonInfo}>삭제</button>

            </div>
        </div>
    )
}

export default Person;

 

App.js 에도 넘길 함수 만들어주기 (삭제부터 )

import './App.css';
import {useState} from 'react' //상태관련 훅 
import Person from './components/Person.js';
import InputComp from './components/InputComp';


function App() {
  const [personList, setPersonList] = useState([
    {id:1, name:'kim', age:20, height:176.6},
    {id:2, name:'lee', age:21, height:162.6},
    {id:3, name:'park', age:22, height:177.8}
  ])
  const addPersonInfo = (id,name,age,height) => {
    alert('추가! (App)')
    alert(id)
    alert(name)
    alert(age)
    alert(height)
    const personObj = {id:id, name:name, age:age,height:height}
    const concatedList = personList.concat(personObj)
    setPersonList(concatedList)
  }

  const deletePersonInfo = (id) =>{
    alert('삭제(App)')
    alert(id) //삭제할 아이디
  }

  const result = personList.map(
    (data)=>(<Person key={data.id} name={data.name}
                    age={data.age}
                    height={data.height}
                    deletePersonInfo={deletePersonInfo}/>)
  )
  return (
    <div className="App">
      <InputComp addPersonInfo={addPersonInfo}/>
      {result}
    </div>
  );
}

export default App;

 

이제 필터 메서드 써서 해당되는 id 삭제 할 수 있도록 만들어주기 

삭제 버튼 누르면 넘어오는 값이 비어있었는데 확인해보니 App.js 에서 result 에 key에 id 값을 적어주지 않았음 

import './App.css';
import {useState} from 'react' //상태관련 훅 
import Person from './components/Person.js';
import InputComp from './components/InputComp';


function App() {
  const [personList, setPersonList] = useState([
    {id:1, name:'kim', age:20, height:176.6},
    {id:2, name:'lee', age:21, height:162.6},
    {id:3, name:'park', age:22, height:177.8}
  ])
  const addPersonInfo = (id,name,age,height) => {
    alert('추가! (App)')
    alert(id)
    alert(name)
    alert(age)
    alert(height)
    const personObj = {id:id, name:name, age:age,height:height}
    const concatedList = personList.concat(personObj)
    setPersonList(concatedList)
  }

  const deletePersonInfo = (id) =>{
    alert('삭제(App)')
    alert(id) //삭제할 아이디

    const filterList = personList.filter(
      (data) => (data.id !== id)
    )
    setPersonList(filterList) // 지워줌 
  }

  const result = personList.map(
    (data)=>(<Person key={data.id} id={data.id} name={data.name}
                    age={data.age}
                    height={data.height}
                    deletePersonInfo={deletePersonInfo}/>)
  )
  return (
    <div className="App">
      <InputComp addPersonInfo={addPersonInfo}/>
      {result}
    </div>
  );
}

export default App;

삭제완료

 

 

이제 수정 기능 만들기 

Person.js 에 useState 임포트 해주기 

import '../css/Person.css'
import {useState} from 'react'

function Person(props){
    const [edit, setEdit] = useState()

    const updatePersonInfo =() =>{
        alert('수정(Person)')
    }
    const deletePersonInfo =() =>{
        alert('삭제(Person)')
        const {id} = props
        props.deletePersonInfo(id)
    }
    return(
        <div id='person'>
            <div>이름 : {props.name}</div>
            <div>나이 : {props.age}</div>
            <div>키 : {props.height}</div>
            <div>
                <button onClick={updatePersonInfo}>수정</button>
                <button onClick={deletePersonInfo}>삭제</button>

            </div>
        </div>
    )
}

export default Person;

 

retrun 값 if 문으로 감싸주기 

edit 이 된 상태와 아닌상태 

edit 상태가 true 인 상태에 input 태그 넣어주기 

 

import '../css/Person.css'
import {useState} from 'react'

function Person(props){
    const [edit, setEdit] = useState(false)

    const updatePersonInfo =() =>{
        alert('수정(Person)')
        setEdit(!edit)
    }
    const deletePersonInfo =() =>{
        alert('삭제(Person)')
        const {id} = props
        props.deletePersonInfo(id)
    }
    if(edit === false){
        return(
            <div id='person'>
                <div>이름 : {props.name}</div>
                <div>나이 : {props.age}</div>
                <div>키 : {props.height}</div>
                <div>
                    <button onClick={updatePersonInfo}>수정</button>
                    <button onClick={deletePersonInfo}>삭제</button>
                </div>
            </div>
        )
    }else if(edit === true){
         return(
             <div id='person'>
                <div>이름 : {props.name}</div>
                <div>나이 : <input type='text'/>{props.age}</div>
                <div>키 : {props.height}</div>
                <div>
                    <button onClick={updatePersonInfo}>수정</button>
                    <button onClick={deletePersonInfo}>삭제</button>
                </div>
            </div>
        )        
    }
}
export default Person;

수정누르면 화면에 인풋 나타나는거 확인되면 onChange 이벤트 걸기 

위에 useState 적어주고 바로 걸어줄 수도 있음 

import '../css/Person.css'
import {useState} from 'react'

function Person(props){
    const [edit, setEdit] = useState(false)
    const [age,setAge] = useState(props.age) // 원래 넘어온값 기존값으로 넣어줘야함 

    const updatePersonInfo =() =>{
        alert('수정(Person)')
        setEdit(!edit)
    }
    const deletePersonInfo =() =>{
        alert('삭제(Person)')
        const {id} = props
        props.deletePersonInfo(id)
    }
    if(edit === false){
        return(
            <div id='person'>
                <div>이름 : {props.name}</div>
                <div>나이 : {props.age}</div>
                <div>키 : {props.height}</div>
                <div>
                    <button onClick={updatePersonInfo}>수정</button>
                    <button onClick={deletePersonInfo}>삭제</button>
                </div>
            </div>
        )
    }else if(edit === true){
         return(
             <div id='person'>
                <div>이름 : {props.name}</div>
                <div>나이 : <input type='text'defaultValue={props.age} 
                            onChange={(e)=>setAge(e.target.value)}/>{props.age}</div>
                <div>키 : {props.height}</div>
                <div>
                    <button onClick={updatePersonInfo}>수정</button>
                    <button onClick={deletePersonInfo}>삭제</button>
                </div>
            </div>
        )        
    }
}
export default Person;

 

 

이제 수정버튼을 두번째 눌렀을때 수정되도록 

updatePersonInfo 함수에 if문 적어주기 

props.deletePersonInfo(id,age) //id 는 검색을 위한 것이고 age 가 바꿀값
 

id 값이 없다고 오류가뜸  -> id는 props.id 로 바꿔주기 

import '../css/Person.css'
import {useState} from 'react'

function Person(props){
    const [edit, setEdit] = useState(false)
    const [age,setAge] = useState(props.age) // 원래 넘어온값 기존값으로 넣어줘야함 

    const updatePersonInfo =() =>{
        alert('수정(Person)')
        if(edit ===true){ //수정가능 화면일때
            props.updatePersonInfo(props.id,age) //id 는 검색을 위한 것이고 age 가 바꿀값 
        }
        setEdit(!edit) // 화면변경
    }
    const deletePersonInfo =() =>{
        alert('삭제(Person)')
        const {id} = props
        props.deletePersonInfo(id)
    }
    if(edit === false){
        return(
            <div id='person'>
                <div>이름 : {props.name}</div>
                <div>나이 : {props.age}</div>
                <div>키 : {props.height}</div>
                <div>
                    <button onClick={updatePersonInfo}>수정</button>
                    <button onClick={deletePersonInfo}>삭제</button>
                </div>
            </div>
        )
    }else if(edit === true){
         return(
             <div id='person'>
                <div>이름 : {props.name}</div>
                <div>나이 : <input type='text'defaultValue={props.age} 
                            onChange={(e)=>setAge(e.target.value)}/></div>
                <div>키 : {props.height}</div>
                <div>
                    <button onClick={updatePersonInfo}>수정</button>
                    <button onClick={deletePersonInfo}>삭제</button>
                </div>
            </div>
        )        
    }
}
export default Person;

 

 

App.js 에도 적어주기 

 

import './App.css';
import {useState} from 'react' //상태관련 훅 
import Person from './components/Person.js';
import InputComp from './components/InputComp';


function App() {
  const [personList, setPersonList] = useState([
    {id:1, name:'kim', age:20, height:176.6},
    {id:2, name:'lee', age:21, height:162.6},
    {id:3, name:'park', age:22, height:177.8}
  ])
  const addPersonInfo = (id,name,age,height) => {
    alert('추가! (App)')
    alert(id)
    alert(name)
    alert(age)
    alert(height)
    const personObj = {id:id, name:name, age:age,height:height}
    const concatedList = personList.concat(personObj)
    setPersonList(concatedList)
  }

  const deletePersonInfo = (id) =>{
    alert('삭제(App)')
    alert(id) //삭제할 아이디

    const filterList = personList.filter(
      (data) => (data.id !== id)
    )
    setPersonList(filterList) // 지워줌 
  }

  const updatePersonInfo=(id,age)=>{
    alert('수정(App)')
    alert(id)
    alert(age)
  }

  const result = personList.map(
    (data)=>(<Person key={data.id} id={data.id} name={data.name}
                    age={data.age}
                    height={data.height}
                    deletePersonInfo={deletePersonInfo}
                    updatePersonInfo={updatePersonInfo}/>)
  )
  return (
    <div className="App">
      <InputComp addPersonInfo={addPersonInfo}/>
      {result}
    </div>
  );
}

export default App;

 

이제 입력한 값으로 바꿔주기 

 

App.js

  const updatePersonInfo=(id,age)=>{
    alert('수정(App)')
    alert(id)
    alert(age)
    //배열수정

    /* 삼점연산자를 안쓴 경우
    const modifiedList = personList.map(
      (data) => 
      (data.id === id) ? ({id:data.id, name:data.name, age:age, height:data.height}) : data // 아니면 그대로(data)
      //아직 바뀌는 값은 age 이기 때문에 나머지값은 data 값임 
    )
    */

    //삼점연산자를 사용한 경우
    const modifiedList = personList.map(
      (data) =>
      (data.id === id) ? ({...data,age:age}) : data // 아니면 그대로(data)
    )
    setPersonList(modifiedList
      )
  }

 

728x90