20230615 TIL(Props,State,이벤트처리)

뿌링클 치즈맛·2023년 6월 16일
0

Elice AI트랙 8기

목록 보기
21/28

Props

const Welcom=(props)=>{
  return <h1> Hello,{props.name}
}
const App = () => {
return <div>
<Welcome name="수영" />
<Welcome name="민수" />
<Welcome name="영희" />
</div>;
}

컴포넌트에 원하는 값을 넘겨줄 때 사용. 변수,함수,객체,배열 등 자바스크립트의 요소라면 제한없이 넘겨줄 수 있다. Props가 변경되면 컴포넌트가 다시 렌더링
된다.부모 컴포넌트에서 자식 컴포넌트로만 전달이 가능하다.

//DOOOOOON'T
const Welcome = (props) => {
props.name = props.name + "님";
return <h1>Hello, {props.name}</h1>;
}

//DOOOOOOOOO
const Welcome = (props) => {
const username = props.name + "님";
return <h1>Hello, {username}</h1>;
}

props의 값을 임의로 변경해서 사용하지 않는 것(=재할당하지 않는 것)이 좋다.
변경해서 사용하고 싶다면 새로운 변수(username)을 생성해 할당하기.

DOM Element의 Attributes

기본적인 DOM 요소들의 Attribuite는 camelCase로 작성한다. (className) data, aria로 시작하는 Attribuite는 예외다. HTML의 Attribuite과 다른 이름을 가지는 Attribuite가 있다.(class=>className,for=>htmlFor) HTML의 Attribuite과 다른 방식을 가지는 Attribuite가 있다.(checked/defaultChecked,value/defaultValue)
jsx
style="background-color:gray"

HTML
style={backgroundColor:'gray'}

style은 string 형식이 아니라 object 형식으로 작성해야 한다.

<input type="checkbox" checked={false} />

위의 코드가 html코드라면 checked의 초기값이 false인 것이지만, 리액트 내에서는 현재 값을 의미한다.
리액트에서 checked의 값이 false로 고정되어 있는 경우에는 사용자가 체크박스를 클릭해도 변화가 일어나지 않는다.
초기값의 의미로 checked/value 를 사용하고 싶다면 defaultChecked/defaultValue를 설정하면 된다.

Attribute(Key)

const Names = () => {
	const names = [
		{key: '1', value: '민수'},
		{key: '2', value: '영희'},
		{key: '3', value: '길동'},
    ]
	return (
      <div>
		{names.map((item) => (
			<li key={item.key}>{item.value}</li>
        ))}
      </div>
)
}

Key는 React가 어떤 항목을 변경, 추가 또는 삭제할지 식별하는 것을 돕는다. Key는 엘리먼트에 안정적인 고유성을 부여하기 위해 배열 내부의 Element에 지정해야 한다.(const names=[{key:'1',value:'민수'},]
Key는 배열 안에서 형제 사이에서 고유해야 하고 전체 범위에서 고유할 필요는 없다.(key1에 민수와 영희를 넣을 수 없음)
두 개의 다른 배열을 만들 때 동일한 key를 사용할 수 있다.

const Welcome = (props) => {
    const { a, b, c } = props;
    return <div>...</div>
}

const Welcome = ({ a, b, c }) => {
    return <div>...</div>
}

구조분해 할당으로 Props를 받아올 수도 있다.위와 아래의 코드는 같은 내용이다.


const Component = (props) => {
  return <h1> Hello,{props.username}! </h1>;
}
const Component = (props) => {
	const {username}=props
    return <h1> Hello,{username}! </h1>;
}

const Component = ({ username }) => {
    return <h1> Hello,{username}! </h1>;
}

props를 할당하는 방법

  1. return <h1> Hello,{props.name}</h1>}```

props를 받고 props의 username 값을 가져와 h1태그 사이에 넣음

2.const Component = (props) => { const {name}=props.name return <h1> Hello,{name}! </h1>;}

props를 받고 props로부터 username 값을 받아와 할당함.

3.const Component = ({ name }) => { return <h1> Hello,{name}! </h1>;}

애초에 username 값을 받아와 바로 사용함

새로 파일을 만들어 컴포넌트를 선언할 때 import React from "react"를 잊지 말자!

//컴포넌트 생성을 위한 js파일
const Student = ({ student }) => {
  return (
    <div>
      {student.name}학생은 {student.subject}를 듣습니다. 현재 점수는
      {student.score}입니다.
    </div>
  );
};
//jsx파일
const Kim={
    name: "KIM",
    subject: "영미문학의 이해",
    score: 80
}
function App(){
  return (
    <>
      <Student student={Kim} />
      </>

컴포넌트 생성을 위한 js파일에서 Student 컴포넌트를 생성해 {}로 student 값을 받아온다.
student 에서 name,subject,score를 찾아 출력한다.
jsx파일에는 Kim 객체를 선언한다. Student 컴포넌트에는 student를 프로퍼티로 주고, 프로퍼티에는 객체가 들어올 수 있으니 student={Kim}으로 컴포넌트에 값을 전달한다.

삼항연산자
student.score >= 80 ? 'PASS' : 'FAIL';
student props에서 score의 값이 80이상일때 PASS, 미만이면 FAIL


State

import { useState } from 'react';
function Example() {
  const [count, setCount] = useState(0);
  return (
    <div>
      <p>버튼을 {count}번 눌렀습니다.</p>
      <button onClick={() => setCount(count + 1)}>클릭
      </button>
    </div>
  );
}

State는 Component 내에서 유동적으로 변할 수 있는 값을 저장한다(count는 버튼이 클릭되는 이벤트가 발생하면 값이 +1된다.) 간단하게 생각하면 변수다.개발자가 의도한 동작에 의해 변할 수도 있고 사용자의 입력에 따라 새로운 값으로 변경될 수도 있다.(setCount(count+1)) State 값이 변경되고 재렌더링이 필요한 경우, React가 자동으로 계산하여 변경된 부분을 렌더링한다. 중요한 것이 이 부분이다. state는 변수와 별반 차이가 없지만 값이 변하는 순간 렌더링이 발생한다. 어제 강의에서는 State를 프로퍼티의 복사본이라고 했었다.

//NO
<button onClick={() => setCount{count = count + 1;}/>
//GOOD
<button onClick={() => setCount{count + 1;}/>

Props와 마찬가지로, State 값은 직접 변경하지 않는 것이 좋다. 리액트가 컴포넌트를 다시 렌더링할 타이밍을 알아차리지 못한다. 반드시 setState함수를 이용해서 값을 변경하자!
setState함수가 호출될 때 리액트에 다시 렌더링 하라는 명령이 내려진다.

State를 변경하는 방법들

  1. setState 내에 변경할 값을 넣기
const [count, setCount] = useState(0);
setCount(count + 1)

2.setState에 함수를 넣기

const [count, setCount] = useState(0);
setCount((current) => {
	return current + 1
}

함수가 반환(return)하는 값으로 State가 변경. 현재 값을 기반으로 State를 변경하려는 경우에는 함수를 넣는 방법이 더 적절하다.

실습문제 풀다가 에러가 발생해서 확인해봤더니 1번의 방법을 사용했기 때문이었다.

  const submitHandle = event => {
    event.preventDefault();
    if (typeof onInsert === 'function') {
      onInsert(inputValue);
    }
    inputValue = '';
  };
  return (
    <form onSubmit={submitHandle}>
      <input
        value={inputValue}
        onChange={current => {
          setValue(current.target.value);
        }}
      />

inputValue를 초기화해야 해서 ''를 바로 할당했더니 'inputValue' is constant no-const-assign 에러가 발생했다. setState(setValue)를 사용해야 하는 이유를 배웠다~!

Arr/Object를 갖는 State를 만들 때 주의할 점

const [user, setUser] =useState({name: "민수", grade: 1})
setUser((current) => {
      current.grade = 2;
      return current;
}

current.grade = 2;로 값이 바뀐 것 같아보이지만 리액트가 State의 변경을 감지하지 못한다.
user Object 안의 grade는 변경되었지만, user 자체가 변경되지 않았기 때문이다. 객체 내의 값을 변경하고 싶으면 새로운 객체를 만들어 grade를 변경하는 것이 좋다.
위 코드에서 current는 매개변수일 뿐이다. 헷갈리지 말자!

const [user, setUser] =
	useState({name: "민수", grade: 1})
	setUser((current) => {
		current.grade = 2;
		return current;
})

잘못된 예시

const [user, setUser] =
	useState({name: '민수', grade: 1 })
	setUser((current) => {
		const newUser = { ...current }//기존 값을 spread 문법으로 전개함
		newUser.grade = 2 //새 객체에 값을 변경함
		return newUser 
}

새 객체 newUser를 만들어 값을 변경해 넣었다.

useState와 setState 차이

useState는 state의 초기값을 정할 수 있고, return 값으로 state, setState를 돌려주는 hook이다.
const [counter, setCounter] = useState(0);
에서 counter가 10에서 11로 바뀌면 렌더링된다. 같은 주소값을 가리킬 때는 렌더링이 되지 않는다.

setState는 state의 값을 변경할 때 사용하는 함수이다.setState는 state의 주소값이 변경되었을 때 렌더링한다. 위의 코드에서 setCounter가 setState이다.

useState를 실행하기 위해서는 import {useState} from "react" 를 사용해야 한다!

<button onClick={() => {}>
리액트에서 버튼에 onclick 주는 방법. 자꾸 까먹어서 메모함

실습문제 함수 진행 과정 자세하게 정리하면서 이해하기!


이벤트

이벤트(event)란 웹 브라우저가 알려주는 HTML 요소에 대한 사건의 발생을 의미한다.

이벤트 처리(핸들링) 방법
1. 핸들링 함수를 선언해 Element에 넘겨주기

const App = () => {
  const handleClick = () => {
    alert("클릭했습니다.");
  }
  return (
    <div>
      <button onClick={handleClick}>클릭하세요</button>
    </div>
  );
};

handleClick이라는 변수에 익명함수를 넣어줬다.

2.익명함수로 처리

const App = () => {
  return (
    <div>
      <button onClick={() => { alert('클릭했습니다.') }}>
        클릭하세요</button>
    </div>
  )
}

button onClick에 익명함수로 () => { alert('클릭했습니다.')를 줬다.


const App = () => {
  const handleChange = (event) => {
    console.log(event.target.value)+ "라고 입력하셨네요.");
  }
  return (
    <div>
      <input onChange={handleChange} />
    </div>
  );
};

handleChange에 이벤트객체를 매개변수로 전달했다. 여기서 event는 handleChange 함수가 onChange 발생하면 실행되므로 onChange를 의미한다.이벤트 객체를 이용하여 이벤트 발생 원인, 이벤트가 일어난 엘리멘트에 대한 정보를 얻을 수 있다. event.target은 이벤트가 일어난 엘리면트(input)을 뜻하고, .value로 그 값을 가져온다.

  const submitHandle = event => {
    event.preventDefault();
    if (typeof onInsert === 'function') {
      onInsert(inputValue);
    }
    setValue('');
  };
  return (
    <form onSubmit={submitHandle}>
      <input
        value={inputValue}
        onChange={current => {
          setValue(current.target.value);
        }}/>

에서 submitHandle이라는 변수에 함수를 넣었고, form에서 submit 이벤트가 발생할 때 submitHandle 함수를 호출한 것을 확인할 수 있다.

컴포넌트 내 이벤트

const App = () => {
	const [inputValue, setInputValue] =useState("defaultValue");
	const handleChange = (event) => {
		setInputValue(event.target.value);
		}
	return (
		<div>
		<input onChange={hadleChange}defaultValue={inputValue} /><br />
        입력한 값은: {inputValue}
      </div>
		);
	};

event object의 target은 이벤트의 원인이 되는 Element를 가리킨다. 위 코드에서 event.target은 input 엘리먼트이므로 input 칸에 입력된 값을 가져와 setState를 한다.
State를 여러 개 선언할 수도 있지만 object를 활용하여 여러 개의 input을 state로 관리할 수도 있다. target으로부터 name을 받아와 해당 name의 key에 해당하는 value를 변경하여 state에 반영한다.

function App() {
  const [inputValue, setValue] = useState();
  return (
    <div className="App">
      <input
        onChange={event => {
          setValue(event.target.value);
        }}
      />
      <span> {inputValue}</span>
    </div>
  );
}

input칸에 입력을 하면 변경사항이 발생할 때 event 인자에 그 변경된 값이 전달된다. 그리고 setValue로 input의 변경값을 inputValue에 넣어준다. const에서 첫번째 인자로(inputValue) 두번째 인자인 콜백함수(setValue)에 넣은 event.target.value를 넣어준다.setState는 state의 값을 변경할 때 사용하는 함수

 const [person, setPerson] = useState({
    name: 'Kim',
    school: 'YALE',
  })

   const handleChange = (event) => {
    const { name, value } = event.target;
    setPerson((current) => {
      const newPerson = { ...current };
      newPerson[name] = value;
      return newPerson;
    });
  };

Kim,YALE은 person의 초기값 이므로 useState()뒤에 넘겨준다.
const {}에서 name는 event.target의 name, value는 event.target의 value를 가져와 저장한다. const newPerson = { ...current };에서 현재의 값들을 복사해 newPerson이라는 새로운 객체에 저장한다. newPerson의 name에는 event.target의 값을 가져와 저장한다.

const MyForm=({onChange})=>{
    return <input onChange={onChange}/>
})

함수를 Props로 전달할 경우()인자 안에 {}를 쓴다.

profile
뿌링클 치즈맛

0개의 댓글