리액트

리액트>input

연습노트 2024. 7. 18. 16:19

<input> 태그 사용하기

 

유저의 입력을 받을 수 있는 박스를 생성하고 싶으면 

html에선 다음과 같은 태그들을 이용가능합니다.

 

<input type="text"/>
<input type="range"/>
<input type="date"/>
<input type="number"/>
<textarea></textarea>
<select></select>

이거 말고도 다양한 종류의 인풋 박스가 많으니 필요할 때 찾아쓰도록 합시다. 

 

 

 

 

 

<input>에 뭔가 입력시 코드를 실행하려면

 

유저가 <input>에 뭔가 입력시 코드를 실행해주고 싶을 때가 많습니다.

그러고 싶으면 onChange 아니면 onInput 이벤트핸들러를 부착하면 됩니다. 

 

 

<input onChange={()=>{ 실행할코드 }}/>

onChange, onInput은

<input>에 유저가 뭔가 입력할 때마다 안에 있는 코드를 실행해줍니다. 

진짜인지 console.log(1) 이런거 넣어서 테스트해봅시다. 

 

 

(참고)

이벤트 핸들러들은 매우 많습니다.

onMouseOver={ } 이건 이 요소에 마우스를 댔을 때 안의 코드를 실행해줍니다.

onScroll={ } 이건 이 요소를 스크롤했을 때 안의 코드를 실행해줍니다.

몇십개 있는데 원하는 이벤트가 있으면 찾아서 사용해봅시다. 

 

 

 

 

 

 

<input>에 입력한 값 가져오는 법

 

<input onChange={(e)=>{ console.log(e.target.value) }}/>

e라는 파라미터를 추가해주고 

e.target.value라고 적으면 현재 <input>에 입력된 값을 가져올 수 있습니다. 

콘솔창에 출력해보니 진짜 가져옵니다. 

 

이벤트핸들러에 들어가는 함수에 저렇게 파라미터 e를 추가하면

e는 이벤트 객체 이런 식으로 부르는데

현재 발생하는 이벤트와 관련한 유용한 기능들을 제공하는 일종의 변수입니다.  

(작명은 e 말고 자유롭게 해도 됩니다)

 

e.target 이러면 현재 이벤트가 발생한 곳을 알려주고

e.preventDefault() 이러면 이벤트 기본 동작을 막아주고

e.stopPropagation() 이러면 이벤트 버블링도 막아줍니다. 이거 쓰면 좋아요버튼 누를 때 모달창도 떠버리는 버그 해결가능

 

 

 

 

 

 

 

사용자가 input에 입력한 데이터 저장하기 

 

사용자가 input에 입력한 데이터는 state 아니면 변수에 저장해서 쓰는게 일반적입니다. 

그래야 편리하기 때문에 일단 저장부터 해봅시다.

state 배운 기념으로 state를 사용합시다. 

 

 

function App (){

  let [입력값, 입력값변경] = useState('');
  return (
    <input onChange={(e)=>{ 
      입력값변경(e.target.value) 
      console.log(입력값)
    }} />
  )
}

state를 하나 만들어주고 onChange될 때 마다 state에 e.target.value 넣으라고 코드를 짰습니다. 

state에 문자를 저장하고 싶은데 일단 기본값을 뭘 넣을지 모르겠으면 따옴표 2개만 치면 됩니다.

따옴표 2개는 빈문자를 뜻합니다. 

이제 입력값이라는 state를 필요한 곳에서 마음대로 사용하면 되겠습니다. 

 

 

 

(참고)

근데 위 코드 실행해보면 a를 입력하면 콘솔창에 아무것도 안뜨지 않습니까

aa를 입력하면 a만 콘솔창에 뜨고요.

 

왜냐면 state 변경함수 특징 때문인데 state 변경함수는 약간 늦게 처리됩니다.

전문용어로 async하게 (비동기적으로) 처리된다고 합니다. 

그리고 자바스크립트에선 늦게 처리되는 코드들은 잠깐 제쳐두고 바로 다음줄을 실행해줍니다. 

그래서 console.log(입력값) 이게 먼저 실행되어서 저렇게 나오는 것일 뿐입니다. 

그냥 실행 순서만 좀 다를 뿐 state변경은 어쨌든 잘 됩니다. 

 

숙제1. 버튼누르면 유저가 입력한 글을 글목록에 추가해주세요

 

그럼 이렇게 코드짜면 되겠군요 

"버튼누르면 유저가 입력한 글 가져와서 그걸로 html을 하나 생성해주세요~"

근데 이건 쌩자바스크립트 방식이고 리액트는 스위치와 전등 만들어놓고 state만 만지면 된다고 했습니다. 

 

"버튼누르면 유저가 입력한 글 가져와서 글제목 state에 넣어주세요"

이렇게 코드짜면 끝입니다. 

왜냐면 지금 글제목.map() 이렇게 코드짠 덕분에 글제목 state 갯수에 맞게 html이 알아서 생성되고 있으니까요. 

 

 

 

 

function App (){
  let [글제목, 글제목변경] = useState(['남자코트추천', '강남우동맛집', '파이썬독학']);
  let [입력값, 입력값변경] = useState('');
  return (
    <div>
      <input onChange={ (e)=>{ 입력값변경(e.target.value) } } />
      <button onClick={()=>{ 
        ???
      }}>글발행</button>
    </div>
  )
}

▲ 글발행 버튼을 하나 만들었는데 이거 누르면 어떤 코드를 실행하면 될까요?

이제 리액트 기초문법시간이 끝났기 때문에 

리액트 지능이 상승할 마지막 기회니까 아직 안해봤다면 직접 해봅시다.

 

전 이렇게 했는데

 

function App (){
  let [글제목, 글제목변경] = useState(['남자코트추천', '강남우동맛집', '파이썬독학']);
  let [입력값, 입력값변경] = useState('');
  return (
    <div>
      <input onChange={ (e)=>{ 입력값변경(e.target.value) } } />
      <button onClick={()=>{ 
        let copy = [...글제목];
        copy.unshift(입력값);
        글제목변경(copy)
      }}>글발행</button>
    </div>
  )
}

발행버튼누르면 글제목state에 유저가 입력한값만 하나 끼워넣으면 됩니다. 

1. 버튼누르면 일단 글제목state를 카피부터했습니다. array 형태의 state 조작은 우선 카피부터하면 된댔습니다.

2. 카피한거에 unshift(입력값) 해줬는데 이게 뭐냐면 array자료 맨 앞에 자료추가하는 문법입니다.

3. 그리고 state변경함수 사용했습니다.

 

그럼 이제 <input>에 뭐 입력하고 발행버튼 누르면 글이 진짜로 발행되는 것 같은 기능이 완성됩니다.

 

 

 

 

 

Q. 저는 state, props, component, map 전부 아는데 코드를 못짜겠어요 뭐임?

A. 그것은 리액트를 못하는게 아니라 프로그래밍 기초가 부실할 뿐이니 안심하셔도 됩니다. 

 

 

[collapse]

 

 

 

 

 

Q. 왜 새로고침하면 없어지죠?

원래 브라우저는 새로고침하면 html, js 파일을 다시 읽습니다. 

다시 읽으면 state나 변수같은 것들도 초기값으로 변경됩니다. 원래그럼 

그래서 실제 서비스였으면 우선 서버로 보내서 DB에 영구저장을 하거나 그랬겠지만

갑자기 서버와 DB 가르치려면 20강 추가해야하니까 프론트엔드에서만 잘 구현해보면 됩니다. 

 

 

 

 

 

 

 

 

숙제2. 글마다 삭제버튼과 기능만들기

 

map 반복문안에 버튼부터 만들면 됩니다.

그 다음에 버튼누르면 

"<div> 하나를 삭제해주세요~" 라고 코드짜는건 틀딱자바스크립트 방식이고

"state에서 글을 삭제해주세요~" 라고 코드짜는건 리액트방식입니다. 

리액트방식으로 코드짜보면 됩니다. 

 

 

 

function App (){
  let [글제목, 글제목변경] = useState(['남자코트추천', '강남우동맛집', '파이썬독학']);
  let [입력값, 입력값변경] = useState('');
  return ( 
    <div>
    { 
     글제목.map(function(a, i){
        return (
          <div className="list">
            <h4>{ 글제목[i] }</h4>
            <p>2월 18일 발행</p>
            <button onClick={()=>{ ? }}>삭제</button>
          </div> 
        )
     }) 
    }  
  </div>
  )
}

▲ 삭제버튼을 글마다 추가해놨는데 이거 누르면 어떤 코드를 실행하면 될까요? 

역시 마지막 찬스입니다. 

 

모르는게 나오면 검색해보면 됩니다

 

 

array자료에서 x번째 데이터를 삭제하고 싶으면

array자료.splice(x, 1) 이라고 사용하면 된다는군요. 

 

 

function App (){
  let [글제목, 글제목변경] = useState(['남자코트추천', '강남우동맛집', '파이썬독학']);
  let [입력값, 입력값변경] = useState('');
  return ( 
    <div>
    { 
     글제목.map(function(a, i){
        return (
          <div className="list">
            <h4>{ 글제목[i] }</h4>
            <p>2월 18일 발행</p>
            <button onClick={()=>{ 
              let copy = [...글제목];
              copy.splice(i, 1);
              글제목변경(copy);
           }}>삭제</button>
          </div> 
        )
     }) 
    }  
  </div>
  )
}

1. 일단 버튼누르면 글제목state 사본부터 만들었습니다.

2. 글제목state에서 x번째 데이터를 삭제하고 싶으면 splice(x, 1) 쓰면 된댔습니다.

그래서 저렇게 써봤습니다. 

 

그럼

0번째 삭제버튼 누르면 copy.splice(0, 1) 해주니까 0번글이 없어집니다.

1번째 삭제버튼 누르면 copy.splice(1, 1) 해주니까 1번글이 없어집니다.

2번째 삭제버튼 누르면 copy.splice(2, 1) 해주니까 2번글이 없어집니다.