일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | ||||
4 | 5 | 6 | 7 | 8 | 9 | 10 |
11 | 12 | 13 | 14 | 15 | 16 | 17 |
18 | 19 | 20 | 21 | 22 | 23 | 24 |
25 | 26 | 27 | 28 | 29 | 30 | 31 |
- 디자인참고
- 자료구조_배열
- Form
- use-strict
- boxshadow
- 정적배열
- github폴더생성
- arrow function
- sectioning Elements
- React
- gitstatus
- 변수타입과 레퍼런스
- html
- gh-pages
- hoisting
- blockscope
- tableTag
- 코딩독학
- Block
- inline
- 컴포넌트
- baekjun
- 선택자우선순위
- html기본태그
- inlineblock
- 피그마기초
- audioTag
- 공부기록
- 이벤트캡쳐링
- 리액트
- Today
- Total
//log my lifestyle
[React] 💻 react완벽가이드(4) 본문
React 완벽가이드 섹션4 - 리액트 State 및 이벤트 다루기
1. 이벤트 핸들러 써보기
const ExpenseItem =(props) => {
function clickHandler(){ } // 함수로 쓰거나
const clickHandler = () => { // 화살표함수로 쓰거나 상관없음
console.log('clicked!')
}
return (
<button onClick={clickHandler}>Change Title</button>
);
}
이벤트리스너를 추가할때 on으로 시작하는 props를 괄호안에 함수이름만 적어주면 된다.
함수이름뒤에 괄호를 추가하면 jsx코드가 리턴될때 코드가 실행된다. 그래서 함수만 지정하고 onClick을 위한 값으로 이 포인터를 전달하고 클릭할때 함수를 실행!
2. State
컴포넌트 함수는 처음 렌더링 된 이후로 다시 호출되지않는다. 어떤 변경사항을 반영하기 위해서 리액트 라이브러리를 import해야함
import React, { useState } from 'react';
useState 는 리액트 라이브러리에서 제공하는 함수(리액트 훅이라고 불림)
컴포넌트 함수가 다시 호출되는 곳에서 변경된 값을 반영하기 위해 state로 값을 정의할 수있게 해주는 함수
모든 훅들은 리액트 컴포넌트 함수안에서 직접적으로 호출되어야함 (함수밖 호출 ❌, 중첩된 함수 안 호출❌)
const [title, setTitle] = useState(props.title);
useState 는 배열을 반환, 첫번째 요소는 현재상탯값을, 두번째 요소로 그값을 업데이트되는 함수를 리턴한다.
배열구조분해를 사용해서 각각을 변수(또는 상수)로 담을수 있다.
const ExpenseItem =(props) => {
const [title, setTitle] = useState(props.title);
const clickHandler = () => {
setTitle('Updated!');
}
return (
<Card className="expense-item">
<ExpenseDate date={props.date} />
<div className="expense-item__description">
<h2>{title}</h2>
<div className="expense-item__price">${props.amount}</div>
</div>
<button onClick={clickHandler}>Change Title</button>
</Card>
);
}
state는 컴포넌트의 인스턴스별로 나뉘어져있다. 즉,컴포넌트 별 인스턴스를 기반으로 독립적인 state를 갖는다.
3. 사용자 입력 리스닝
import react, { useState } from 'react';
const ExpenseForm = () => {
const [enteredTitle, setEnteredTitle] = useState('');
const titleChangeHandler = (event) => {
setEnteredTitle(event.target.value);
};
return (
<input type='text' onChange={titleChangeHandler} />
)
입력에 대해 변경이벤트를 수신할때, 입력 요소값을 읽는다면 항상 문자열로 얻게됨
useState 다른방식으로 쓰기
const ExpenseForm = () => {
const[userInput,setUserInput]= useState({
enteredTitle:'',
enteredAmount:'',
enteredData:'',
})
const titleChangeHandler = (event) => {
setUserInput({
...userInput,
enteredTitle: event.target.value,
})
};
return (
state를 한번 호출해서 객체로 여러개 다룰수 있다.
이전방식과 차이점은 state를 업데이트를 할때마다 한개가아니라 예시의 세 프로퍼티 모두 업데이트 해야한다는점
하나의 객체에서 업데이트할때마다 이전state는 대체되고 사라질 수 있기때문에 spread연산자를 사용해서 기존값 복사하기
하지만 이 코드보단 아래코드처럼 쓰길 권장한다!
const titleChangeHandler = (event) => {
//setUserInput에 전달하는 이 함수는 리액트에 의해 자동으로 실행
setUserInput((prevState) => {
return { ...prevState, enteredTitle: event.target.value };
});
};
리액트는 state update 스케쥴을 갖고 있고, 그걸 바로 실행하지 않는다.
그래서 동시에 많은 상태 업데이트를 계획할때 오래되거나 ,잘못된 상태 스냅샷에 의존할수있음
이 접근방법은 최신 상태의 스냅샷에서 작업하도록 하는좀 더 안전한 방법!
4.양식 제출 처리
const submitHandler = (event) => {
event.preventDefault(); //submit시 화면이 리로드되는거 방지
const expenseData = {
title: enteredTitle,
amount: enteredAmount,
date: new Date(enteredDate)
};
console.log(expenseData);
// 값을 저장했으면 초기화
props.onSaveExpenseData();
setenteredTitle('');
setenteredAmount('');
setenteredDate('');
};
return (
<form onSubmit={submitHandler}> //form에 submit이벤트 등록
<div>
<div>
<label>title</label>
<input
type='text'
value={enteredTitle} //input에서 value속성을 {enteredTitle}로 지정, 다른input에도해당값 동일처리
/>
</div>
</div>
<button type='submit'>Add Expense</button>
state 양방향바인딩 / 변경되는 입력값만 수신하는것이 아니라 입력에 새로운 값을 다시 전달할수 있음
5.자식 대 부모 컴포넌트 통신(상향식)
1.부모 컴포넌트로부터 자식 컴포넌트로 함수를 전달
2.자식 컴포넌트에서 그 함수를 호출
3.호출했을때 함수에 매개변수로 데이터를 전달
App.js
└ NewExpense.js
└ ExPenseForm.js //expense에서 생성한 데이터를 app컴포넌트에 전달하고싶음
여기서 중간 컴포넌트 생략할 수는 없음 - 단계별로 전달해야한다.
const NewExpense = (props) => {
const saveExpenseDataHandler = (enteredExpenseData) => { ///ExpenseForm에서 제출된 데이터가 매개변수로
const expenseData = {
...enteredExpenseData, //ExpenseForm에서 제출된 데이터
};
props.onAddExpense(expenseData);
}
return <div>
<ExpenseForm onSaveExpenseData={saveExpenseDataHandler} /> //함수자체가 ExpensForm으로전달
</div>
};
export default NewExpense;
먼저 부모컴포넌트에서 함수를 만들고, 리턴문에 자식컴포넌트의 props 를 지정한다.
함수를 통해 포인터를 전달 -> 컴포넌트끼리 , 자식에서 부모컴포넌트로 소통하는방법
const ExpenseForm = (props) => { // props전달
const submitHandler = (event) => {
event.preventDefault();
const expenseData = {
title: enteredTitle,
amount: enteredAmount,
date: new Date(enteredDate),
};
//포인터로 전달받은 함수를 호출할수 있음, 매개변수로 데이터를 전달
props.onSaveExpenseData(expenseData);
setEnteredTitle('');
setEnteredAmount('');
setEnteredDate('');
};
자식 컴포넌트에서 전달받은 함수를 호출한다. 그러면 부모컴포넌트에서는 자식컴포넌트에서 저장된 배열을 받아올수있음
//REF.
https://www.udemy.com/course/best-react/
강의를 듣고 정리한 학습노트입니다 :)
'Web > React' 카테고리의 다른 글
[React] 💻 react완벽가이드(6) (0) | 2022.05.18 |
---|---|
[React] 💻 react완벽가이드(5) (0) | 2022.05.16 |
[React] 💻 react완벽가이드(3) (0) | 2022.05.09 |