패스트캠퍼스 메가바이트스쿨 Day 29 (6주차 목요일) -React 공식문서 뽀개기 3 Form

ctaaag·2022년 5월 18일
0
post-thumbnail

1. form

🚀 개요

  • react에서 form에 접근하기 위해서는 기본적으로 state를 활용한다.
  • hook의 useState를 활용해서 component를 활용할 수 있다고 보면 되는데, 이렇게 state를 통해 control이 가능한 것을 controlledComponent라고 하고, 대표적으로 input, textarea, select가 있다.
  • 그렇다면 UncontrolledComponent도 있는가? 그렇다. 값들을 직접 하지 못하고, reference를 통해서 접근을 해야하는 것들이 있다. 바로 외부에서 ref를 받아오는 경우가 그렇다.


2. ControlledComponent

export default function ControlledComponent() {

  const [name, setName] = useState("")
  const [essay, setEssay] = useState("Please write an essay about your favorite DOM element.")
  const [flavor, setFlavor] = useState("coconut")

  function handleChange(event) {
    const type = event.target.type;
    if (type === 'text') {
      setName(event.target.type);
    }
    if (name === 'essay') {
      setEssay(event.target.value)
    }
    if (name === 'flavor') {
      setFlavor(event.target.value)
    }
  }

  // function handleEssayChange(event) {
  //   setEssay(event.target.value);
  // }

  // function handleFlavorChange(event) {
  //   setFlavor(event.target.value);
  // }

  function handleSubmit(event) {
    alert(`name: ${name}, essay: ${essay}, flavor : ${flavor}`);
    event.preventDefault();
  }
  return (
    <form onSubmit={handleSubmit}>
      <label>
        Name:
        <input name="name" type="text" value={name} onChange={handleChange} />
      </label>
      <br />
      <br />
      <label>
        Essay:
        <textarea name="essay" onChange={handleChange} />
      </label>
      <br />
      <label>
          Pick your favorite flavor:
          <select name="flavor" onChange={handleChange}>
            <option value="grapefruit">Grapefruit</option>
            <option value="lime">Lime</option>
            <option value="coconut">Coconut</option>
            <option value="mango">Mango</option>
          </select>
        </label>
      <br />
      <input type="submit" value="Submit" />
    </form>
  )
}

  • 다음과 같이 input, textarea, select를 활용해서 간단한 입력 form을 만들었다.
  • 각각의 요소를 리액트에서 접근할 때 무엇을 주의해야하는지 알아보자

🚀 Input

export default function ControlledComponent() {
  const [name, setName] = useState("")
  function handleChange(event) {
    setName(event.target.value)
  }
  function handleSubmit(event) {
    alert(`name: ${name}, essay: ${essay}, flavor : ${flavor}`);
    event.preventDefault();
  }
  return (
    <form onSubmit={handleSubmit}>
      <label>
        Name:
        <input name="name" type="text" value={name} onChange={handleChange} />
      </label>
  )
}
  • input을 구성하는 코드는 위와 같다.
  • 여기서 name input 태그의 입력한 값을 name으로 하고, 해당 값의 변경을 추적하기위해 useState를 통해 setname(event.target.value)로 값을 넣어줬다.
  • submit을 누르면 해당 정보를 alert으로 띄워주는 코드를 만들었다.
  • 여기서 주의해야할 점은 input의 value는 항상 state로 통제하고, 변화값을 추적하는 것은 함수 컴포넌트로 따로 빼서 별도로 저장해준다는 것이다.

🚀 Textarea

const [essay, setEssay] = useState("Please write an essay about your favorite DOM element.")
return (
    <form onSubmit={handleSubmit}>
      <label>
        Name:
        <input name="name" type="text" value={name} onChange={handleChange} />
      </label>
      <br />
      <br />
      <label>
        Essay:
        <textarea name="essay" value={essay} onChange={handleChange} />
      </label>
)
  • textarea 역시 value를 essay라는 state를 통해서 주었고, state의 useState hook을 이용해서 따로 정의내리고, setEssay의 값은 handlchange로 따로 함수로 빼서 관리하고 있다.

🚀 Select

  const [flavor, setFlavor] = useState("coconut")
  return (
      <label>
          Pick your favorite flavor:
          <select name="flavor" value={flavor} onChange={handleChange}>
            <option value="grapefruit">Grapefruit</option>
            <option value="lime">Lime</option>
            <option value="coconut">Coconut</option>
            <option value="mango">Mango</option>
          </select>
        </label>
	)
  • select의 구조 역시 위의 것들과 동일하다. 각각의 선택에 따라 flavor라는 state에 값을 넣어주고 있다. 초기 값을 coconut으로 설정했다.

🚀 다중 입력 제어하기

  function handleChange(event) {
    const type = event.target.type;
    if (type === 'text') {
      setName(event.target.type);
    }
    if (name === 'essay') {
      setEssay(event.target.value)
    }
    if (name === 'flavor') {
      setFlavor(event.target.value)
    }
  }
  • 만약 입력 제어 함수가 굉장히 단순한 것이고, 각 요소를 제어하는 것이 비슷하다면 하나의 함수 컴포넌트에서 여러가지 입력을 제어할 수 있다.
  • 위와 같이 각각의 요소마다 name 혹은 type을 통해서 조건문을 걸어줘서 해당 조건을 부합할 때 setState로 값을 넘겨주는 것이 가능하다.
  return (
    <form onSubmit={handleSubmit}>
      <label>
        Name:
        <input name="name" type="text" value={name} onChange={handleChange} />
      </label>
      <br />
      <br />
      <label>
        Essay:
        <textarea name="essay" onChange={handleChange} />
      </label>
      <br />
      <label>
          Pick your favorite flavor:
          <select name="flavor" onChange={handleChange}>
            <option value="grapefruit">Grapefruit</option>
            <option value="lime">Lime</option>
            <option value="coconut">Coconut</option>
            <option value="mango">Mango</option>
          </select>
        </label>
      <br />
  • 이렇게 되면 해당 값의 함수를 모두 만들어서 각각의 변화값을 같은 함수로 통제할 수 있다. 위의 코드가 onChange={handleChange}로 같은 것을 통해서 예를 들 수 있다.


3. UncontrolledComponent

export default function UncontrolledComponent() {
  const fileInputRef = useRef(null);
  
  function handleSubmit(event) {
    event.preventDefault();
    alert(
      `Selected file - ${fileInputRef.current.files[0].name}`
    );
  }

  return (
    <form onSubmit={handleSubmit}>
      <label>
        Upload file:
        <input type="file" ref={fileInputRef} />
      </label>
      <br />
      <button type="submit">Submit</button>
    </form>
  )
}

🚀 ref활용

  • file upload 하는데 해당 파일에 대한 통제는 uncontroll하기 때문에 useRef 훅을 통해서 초기값은 Null로 설정하고 불러오기 위해서 current의 파일로 불러오고 있다.
  • ref로 불러올 땐 useRef를 사용하고, current로 불러오는 구조에 대해서 꼭 인지하자!
profile
프로그래밍으로 지속가능한 세상을 꿈꾸며

0개의 댓글