JiSoo's Devlog
[Udemy React 완벽 가이드] Section 4 본문
이벤트 리스닝 및 이벤트 핸들러 수행하기
- 모든 이벤트 핸들러 props는 값으로 함수가 필요하다
- onClick과 다른 on props에 대한 값으로 전달된 함수는 이벤트가 발생했을 때 실행되어야 한다
<button onClick={() => {console.log("Clicked!");}}>Change Title</button>
const ExpenseItem = (props) => {
const clickedHandler = () => {
console.log("Clicked!!!!");
};
return (
<Card className="expense-item">
<ExpenseDate date={props.date} />
<div className="expense-item__description">
<h2>{props.title}</h2>
<div className="expense-item__price">${props.amount}</div>
</div>
<button onClick={clickedHandler}>Change Title</button>
</Card>
);
};
- 함수 따로 지정해서 onClick={clickedHandler}로 지정만 해줘도 됨
- 일부 이벤트는 특정한 요소에서만 사용 가능하지만 그건 모두 기본적인 DOM의 동작에 기반한다
- 만약 요소가 이벤트를 지원한다면 on 다음에 이벤트명 props를 추가해서 리액트로 리스너를 추가할 수 있다
- 이벤트명은 대문자로 시작(onClick)
- 함수의 명명은 함수가 이벤트에 의해 트리거된다면 이름 뒤에 Handler를 붙이는 게 좋
컴포넌트 함수가 실행되는 방법
- let으로 변수 선언해 주고 처음에는 props.title로 주고 title 변수를 JSX 코드에서 사용해 품명을 아웃풋 한다
const ExpenseItem = (props) => {
let title = props.title;
const clickedHandler = () => {
console.log("Clicked!!!!");
};
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={clickedHandler}>Change Title</button>
</Card>
);
};
- 이렇게 해준 이유는 title이 변수이기 때문에 clickHandler가 실행될 때마다 바꿀 수가 있다
- 리액트는 JSX 코드에서 마주치는 모든 컴포넌트 함수를 계속해서 호출하고 이 함수들이 리턴했을 수도 있는 모든 함수를 호출한다
- 리액트는 앱이 처음 렌더링 될 때 모든 과정을 한 번 거치지만 그리고 끝이다 하지만 오늘날의 앱은 화면에 표시되는 내용을 업데이트해야 하는 게 당연하다
- 그렇게 때문에 우리에겐 리액트에 변경된 사항이 있으며 특정 컴포넌트가 재평가되어야 한다는 사실을 말해줄 방법이 필요하다
state와 함께 일하기
const clickedHandler = () => {
title = "Updated!";
console.log(title);
};
- 여기서 바뀌는 title은 데이터
- 이 컴포넌트가 재평가되고 이 title 데이터에 변동 사항이 생기면 화면에도 반영되어야 한다
- 기본적으로 일반 변수들은 재평가를 트리거 하지 않는다
- 변수가 바뀐 걸로 함수로 다시 실행하지 않는다
- 리액트에 재실행하라고 알려주려면 리액트 라이브러리에서 어떤 것을 가져오기 해야 한다 -> named import (지정해서 가져오기)
- 중괄호를 추가하고 리액트 라이브러리에서 추가하고 싶은 것을 지정하면 된다
import React, { useState } from "react";
- useState는 리액트 라이브러리가 제공하는 것으로 값을 상태로 정의할 수 있도록 해주어 값에 변화가 생기면 다시 호출하는 컴포넌트 함수에 반영이 된다
- useState는 리액트 훅이라고 부르는 것인데 모든 리액트 훅은 이름이 'use'로 시작한다
- 모든 훅은 컴포넌트 함수 안에서 직접 호출돼야 하고 중첩 함수 안에서 호출될 수 없다
- useState는 기본 상태 값을 원한다
useState(props.title); // 초깃값을 인자로
- useState는 단지 리턴만 하는 것이 아니라 해당 변수에 새 값을 할당하기 위해 호출할 수 있는 함수를 리턴해준다 -> 상태 변수가 작동하는 방식
- 배열 구조 할당 - 두 요소를 각각의 변수 또는 상수에 저장한다, 순서가 중요하다
const [title, setTitle] = useState(props.title);
- 첫 번째 값은 관리되는 해당 값에 대한 포인터, 현재 상태 값
- 처음에는 props.title, 즉 props.title에 저장된 값
- 두 번째 요소는 나중에 새 품명을 설정할 때 호출할 함수
- useState는 늘 두 요소로 구성된 배열을 리턴한다
- 첫 번째 값은 늘 현재의 상태 값이며 두 번째 요소는 그것을 업데이트하는 함수이다
const clickedHandler = () => {
setTitle("Updated"); //상태 업데이트 함수 호출
console.log(title);
};
- 상태 업데이트 함수를 호출할 때마다 이 특별한 변수는 새 값을 수신할 뿐만 아니라 상태 업데이트 함수를 호출한 setTitle(), 상태를 초기화한 컴포넌트 함수 useState(props.title)를 재실행한다
- 데이터 변화가 사용자 인터페이스에 반영되어야 한다면 상태가 필요, 일반 변수로는 반영X
"상태" 다루기
- 버튼 클릭하면 가격이 $100에서 $75로 변경되어야 함
import React , { useState } from 'react';
import './styles.css';
export default function App(){
const [price,setPrice] = useState(100)
const clickedHandler = () => {
setPrice(75);
};
return (
<div>
<p>${price}</p>
<button onClick={clickedHandler}>Apply Discount</button>
</div>
);
}
useState Hook 자세히 살펴보기
- useState는 특정 컴포넌트 인스턴스에 대한 상태를 등록한다
- ExpenseItem을 호출할 때마다 새로운 상태가 생성되는데 생성되는 방식은 같지만 리액트는 각각을 독립적으로 관리한다 -> 각각 자체적인 상태가 있다 => 컴포넌트 인스턴스 단위 기반!
- 상태는 컴포넌트 인스턴스 별로 구별된다
- 상태가 업데이트되면 업데이트 함수를 호출한다
- 상태가 업데이트되면 컴포넌트 함수도 재실행된
- 등호를 이용해 값을 할당하지 않고 setTitle('Updated') 이런식으로 상수 사용
- 컴포넌트 함수가 재실행될 때마다 새로운 상태의 스냅샷을 얻는 것이다
- 애플리케이션에 반응성을 부여하는 건 상태이다
- 상태가 없다면 사용자 인터페이스는 그대로일 것이다
- 상태가 있고 이벤트를 수신할 수 있다면 사용자 인풋에 반응할 수 있고 인풋에 따라 화면에 보이는 내용도 바뀔 수 있다
- useState로 상태를 등록해주고 값은 두 개 리턴(값 자체, 업데이트 함수)하고 상태가 변해야 할 때마다 업데이트 함수 호
양식 입력 추가하기
- 사용자가 비용 데이터를 입력할 수 있는 폼 렌더링
- 폼도 별도의 컴포넌트도 분리해 주는데 폼의 로직은 전용 컴포넌트에서 작동한다
- 리액트에서 input 태그는 시작 태그와 종료 태그 사이에 아무 내용이 없기 때문에 자체 closing 태그로 써줘야 한다
- input type="date"에서 min과 max 시작과 종료 날짜, 이를 추가해 주는 이유는 추후에 연도별로 제공하는 필터 추가할 계획이기 때문에
NewExpense.js
import React from "react";
import "./NewExpense.css";
import ExpenseForm from "./ExpenseForm";
const NewExpense = () => {
return (
<div className="new-expense">
<ExpenseForm />
</div>
);
};
export default NewExpense;
ExpenseForm.js
import React from "react";
import "./ExpenseForm.css";
const ExpenseForm = () => {
return (
<form>
<div className="new-expense__controls">
<div className="new-expense__control">
<label>Title</label>
<input type="text" />
</div>
<div className="new-expense__control">
<label>Amount</label>
<input type="number" min="0.01" step="0.01" />
</div>
<div className="new-expense__control">
<label>Date</label>
<input type="date" min="2019-01-01" max="2022-12-31" />
</div>
</div>
<div className="new-expense__actions">
<button type="submit">Add Expense</button>
</div>
</form>
);
};
export default ExpenseForm;
App.js
import React from "react";
import Expenses from "./components/Expenses/Expenses";
import NewExpense from "./components/NewExpense/NewExpense";
const App = () => {
const expenses = [
{
id: "e1",
title: "Toilet Paper",
amount: 94.12,
date: new Date(2020, 7, 14),
},
{ id: "e2", title: "New TV", amount: 799.49, date: new Date(2021, 2, 12) },
{
id: "e3",
title: "Car Insurance",
amount: 294.67,
date: new Date(2021, 2, 28),
},
{
id: "e4",
title: "New Desk (Wooden)",
amount: 450,
date: new Date(2021, 5, 12),
},
];
return (
<div>
<NewExpense />
<Expenses items={expenses} />
</div>
);
};
export default App;
사용자 입력 수신하기
- onChange는 모든 input 타입에 같은 이벤트를 사용할 수 있다
.
- 여기서 함수 실행하는 게 아니기 때문에 함수를 지목만!
- 지정해 준 함수에서도 기본 자바스크립트 문법과 같이 event 객체를 자동으로 얻을 수 있다
- 기본적으로 onChange 프로퍼티를 통해 리액트에 이 함수를 입력했기 때문에 리액트 또는 브라우저 자체에서 change 이벤트가 발생할 때 event 객체를 얻도록 해줄 것이다
- value 프로퍼티에 이벤트가 발생한 시점에 입력되어 있는 값이 들어 있다
const titleChangeHandler = (event) => {
console.log(event.target.value);
};
여러 상태 사용하기
- 값을 저장하고 함수가 재실행 되어도 컴포넌트가 재평가되어도 값이 남아 있도록 하기 위해서 상태를 활용할 것
const [enteredTitle, setEnteredTitle] = useState('');
//괄호 안에 input에 대한 상태 설정, 처음에는 빈 문자열-> 이 컴포넌트가 처음 렌더링 될 때는 아직 아무것도 입력되지 않을 거기 때문
//구조분해할당을 활용해 두 개의 요소를 얻는다
- 사용자가 무언가를 입력하면서 발생하는 이벤트에 반응할 때 setEnteredTitle을 호출해 event.target.value 즉, 현재 입력된 값을 매개변수로 setEnteredTitle의 인자로 입력할 수 있다 -> 그러면 상태에 저장될 것이다
- 나중에 컴포넌트를 업데이트하고 다시 렌더링 하는 데 어차피 상태가 필요할 것이기 때문에 이점이 있다
- 같은 컴포넌트 안에 있는 여러 개의 상태는 완전히 구별된다
- useState( ) -> 괄호 안에는 문자열로 받아서 문자열로 상태를 초기화
const [enteredTitle, setEnteredTitle] = useState("");
const [enteredAmount, setEnteredAmount] = useState("");
const [enteredDate, setEnteredDate] = useState("");
const titleChangeHandler = (event) => {
setEnteredTitle(event.target.value); //상태 저장
};
const amountChangeHandler = (event) => {
setEnteredAmount(event.target.value);
};
const dateChangeHandler = (event) => {
setEnteredDate(event.target.value);
};
상태 하나 사용하기
- 여러 개의 상태 슬라이드를 사용해도 된다
- 세 상태 모두 같은 폼에 연결되어 있으며 세 상태 모두 같은 사용자 인풋을 저장하므로 기본적으로 같은 개념이 세 번 반복되는 것이다
- useState( ) 값으로 객체를 입력하면 되는데 문자열이나 숫자가 아니라 객체라는 것
- useState를 한 번만 호출하고 값으로 객체를 입력하면 된다
useState({
enteredTitle:'',
enteredAmount:'',
enteredDate:''
})
- 상태를 업데이트할 때 하나가 아니라 세 개의 프로퍼티를 모두 업데이트해줘야 한다
const [userInput, setUserInput] = useState({
enteredTitle: "",
enteredAmount: "",
enteredDate: "",
});
const titleChangeHandler = (event) => {
setUserInput({
...userInput, // 객체를 선택해 모든 키-값 쌍을 가져와 새 객체에 추가하는 것
enteredTitle: event.target.value, // 이거 말고 나머지 두 데이터도 놓치지 않도록!
});
};
const amountChangeHandler = (event) => {
setUserInput({
...userInput,
enteredAmount: event.target.value,
});
};
const dateChangeHandler = (event) => {
setUserInput({
...userInput,
enteredDate: event.target.value,
});
};
이전 상태에 의존하는 상태 업데이트
setUserInput({
...userInput,
enteredTitle: event.target.value,
});
- 여기서 상태를 업데이트할 때 이전 상태에 의존하는 이유는 상태를 세 개 만드는 접근법이 아닌 하나의 상태만 활용하는 접근법을 사용했기 때문이다, 다른 값들을 잃지 않도록 복사해 줘야 했다
- 따라서 이전 상태의 스냅샷에 기대서 기존의 값을 복사한 뒤 새 값으로 이전 값을 오버라이드 한 것
- 상태를 업데이트할 때 이전 상태에 의존할 경우 또는 1씩 증가하는 카운터를 관리하는 경우에도 상태를 업데이트하고 이전 상태에 의존한다면 저런 식으로 가 아니라 상태 업데이트 함수의 대체 양식을 사용해야 한다
- setUserInput 함수를 호출한 다음 이 안에 익명 화살표 함수처럼 함수를 넣어야 한다
- setUserInput에 입력한 함수는 리액트가 자동으로 실행시킬 것이다
- 그리고 업데이트 함수를 호출하는 그 상태에 대한 이전 상태 스냅샷을 받아야 한다
- 이전 상태 스냅샷을 얻고 나면 그 아래에 새 상태 스냅샷을 리턴해야 한다
- 전개 연산자(...prevState)로 이전 상태에서 키-값 쌍을 복사한 다음 enteredTitle을 event.target.value로 오버라이드 한다
- 다수의 상태 업데이트를 동시에 예약할 경우 오래되었거나 잘못된 상태 스냅샷에 의존하게 될 수도 있다
const titleChangeHandler = (event) => {
setUserInput((prevState) => {
return { ...prevState, enteredTitle: event.target.value };
});
};
- 이 내부 함수에서 제공하는 상태 스냅샷이 예약된 모든 상태 업데이트를 기억하고 항상 최신 상태 스냅샷이 되도록 보장해 준다
- 이전 상태에 의존해 상태를 업데이트할 경우에는 꼭 이 함수 양식 사용하기
양식 입력에 상태 사용하기
- 입력한 문자 메시지가 유효한 경우(길이가 3글자 이상) 입력 필드 아래에 Valid message라는 텍스트 표시
- 유효하지 않으면 Invalid message라는 텍스트 표시
import React, { useState } from 'react';
import './styles.css';
export default function App() {
const [messageValidity, setMessageValidity] = React.useState('Invalid');
function messageChangeHandler(event){
//할일:로직 추가하기
const value = event.target.value; //입력된 값을 추출하고 조건에 따라 상태 업데이트
if(value.trim().length<3){
setMessageValidity('Invalid');
}
else{
setMessageValidity('Valid');
}
}
return (
<form>
<label>Your message</label>
<input type="text" onChange={messageChangeHandler}/>
<p>{messageValidity} message</p>
</form>
);
}
이전 상태 기반으로 상태 업데이트하기
- "증가" 버튼 클릭할 때마다 증가하는 기본 카운터 만들기
import React from 'react';
import './styles.css';
export default function App() {
const [counter, setCounter]= React.useState(0);
function incrementCounterHandler(){
setCounter(prevCounter => prevCounter + 1);
}
return (
<div>
<p id="counter">{counter}</p>
<button onClick={incrementCounterHandler}>Increment</button>
</div>
);
}
- 이전 값을 기반으로 일부 상태를 업데이트할 때는 상태 업데이트 함수(setCounter)에 함수 전달해야 한다
대안: 공유 핸들러 함수 생성하기
- 여러 개의 핸들러 함수를 하나로
- event 대신 인자 이름과 값을 받는다
- 하나의 함수로 인풋 요소 전부를 대상으로 발생하는 onChange 이벤트를 처리하려는 것
- 인자 이름과 값으로 각각의 인풋 요소를 식별해야 한다
const inputChangeHandler = (identifier, value)=> {
if(identifier === 'title'){
setEnteredTitle(value);
} else if (identifier === 'date'){
setEnteredDate(value);
} else {
setEnteredAmount(value);
}
- onChange에 inputChangeHandler로 그냥 넘기며 안된다
- 새 익명 화살표 함수를 호출해 줘야 하는 곳에 생성한다
- 이 화살표 함수는 인풋에 변경이 발생할 때마다 리액트가 발생시켜준다
- 인풋이 제목용 인풋이니까 첫 번째 인자로 식별자를 'title'을 넣어주어 if 문으로 들어갈 수 있게 한다
- 두 번째 인수는 변경된 값을 넣어준다 -> event.target.value
import React, { useState } from "react";
import "./ExpenseForm.css";
const ExpenseForm = () => {
const [enteredTitle, setEnteredTitle] = useState("");
const [enteredAmount, setEnteredAmount] = useState("");
const [enteredDate, setEnteredDate] = useState("");
const inputChangeHandler = (identifier, value)=> {
if(identifier === 'title'){
setEnteredTitle(value);
} else if (identifier === 'date'){
setEnteredDate(value);
} else {
setEnteredAmount(value);
}
}
return (
<form>
<div className="new-expense__controls">
<div className="new-expense__control">
<label>Title</label>
<input type="text" onChange={(event)=>inputChangeHandler('title', event.target.value)} />
</div>
<div className="new-expense__control">
<label>Amount</label>
<input
type="number"
min="0.01"
step="0.01"
onChange={(event)=>inputChangeHandler('amount', event.target.value)}
/>
</div>
<div className="new-expense__control">
<label>Date</label>
<input
type="date"
min="2019-01-01"
max="2022-12-31"
onChange={(event)=>inputChangeHandler('date', event.target.value)}
/>
</div>
</div>
<div className="new-expense__actions">
<button type="submit">Add Expense</button>
</div>
</form>
);
};
export default ExpenseForm;
양식 제출 처리하기
- 버튼 타입이 submit이고 form 요소 안에서 클릭되면 이 form 요소 자체에서 이벤트를 발생시키고 그 이벤트를 수신해야 한다
- 그래서 form이 대상이 된다
- 이건 브라우저의 기본 기능 - 폼에서 제출했을 때 개발서버한테 넘어감
const submitHandler = (event) => {
event.preventDefault(); //preventDefault 메서드는 자바스크립트의 기본 메서드
};
- 요청이 자동으로 발송되는 기본 기능을 막아주기 때문에 페이지가 다시 로딩되지 않는다
- 현재 로딩돼 있는 페이지가 그대로 있는 상태이고 요청을 어디에도 보내지 않고 상황을 처리할 수 있다
const submitHandler = (event) => {
event.preventDefault();
const expenseData = { //객체 생성
title: enteredTitle,
amount: enteredAmount, //오른쪽은 상태변수 나타냄
date: new Date(enteredDate), //날짜 문자열 파싱해서 날짜 객체로 변환
};
console.log(expenseData);
};
양방향 바인딩 추가하기
- 인풋 필드의 입력값 비워주기
- 양방향 바인딩이란 인풋 요소에 발생하는 변경사항을 수신하는 것뿐 아니라 인풋 요소에 새 값을 넣을 수 있다는 뜻
- 즉 코드를 이용해 인풋의 값을 초기화하거나 바꿀 수 있다는 것
- value라는 속성을 추가해 주면 되는데 이것은 인풋 요소의 기본 속성이기도 하다
- 내부 속성인 value에 값을 지정해 주는 것이다
- 인풋에 발생한 변경 사항을 수신해 상태를 업데이트하는 것뿐 아니라 상태를 다시 인풋 요소에 전달해서 상태가 바뀌었을 때 인풋 요소도 바꿔준다
- 이 방식의 이점은 양식이 제출됐을 때 이렇게 setEnteredTitle을 호출해서 빈 문자열로 인풋을 채울 수 있다
- value를 추가하고 enteredTitle을 가리키게 한다
- 양방향 바인딩은 양식 작업을 할 때 유용하다
- 사용자의 입력을 받을 수도 있고 그 값을 우리가 바꿔 넣을 수도 있다
☆자식-부모 컴포넌트 통신(상향식)
- 우리가 폼으로 수집하고 생성한 데이터를 전달해야 한다. ExpenseForm에서 App 컴포넌트로
- 속성은 부모와 자식 사이에서만 전달이 가능하고 중간 컴포넌트를 건너뛸 수 없다
- 먼저 지출 데이터를 NewExpense로 전달해야 한다
- ExpenseForm에 넣어주는 속성의 값은 함수이고 이 함수는 컴포넌트에서 뭔가 발생했을 때 호출된다
- 사용자가 입력된 지출 데이터를 저장할 때 (양식이 제출됐을 때)
NewExpense.js
import React from "react";
import "./NewExpense.css";
import ExpenseForm from "./ExpenseForm";
const NewExpense = () => {
const SaveExpenseData = (enteredExpenseData) => { //인자로는 입력된 지출 데이터
const expenseData = {
...enteredExpenseData, //submitHandler에서 생성했던 객체
id: Math.random().toString(), //새 키 추가
};
console.log(expenseData);
};
return (
<div className="new-expense">
<ExpenseForm onSaveExpenseData={SaveExpenseData} /> //함수를 가리키는 포인터가 ExpenseForm에 전달되는 것
</div>
);
};
export default NewExpense;
- 중요한 것은 ExpenseForm에서 실행한다는 것
- 실행할 수 있는 이유는 여기서 받는 onSaveExpenseDate 키를 통해 받는 값이 함수(SaveExpenseData)이기 때문이다
- onSaveExpenseData 속성을 통해 포인터를 전달했기 때문에 다른 컴포넌트에서 함수 실행 가능
- submitHandler에서 생성한 데이터를 인수로 넘긴다
- 이렇게 값을 전달해 주고 NewExpense에서 인자 형태로 그 값을 받는다
- 함수 포인터가 saveExpenseDateHandler
- 함수 준비하고 속성에 함수 포인터를 넘겨야 하는데 그 함수를 호출해서 데이터를 위로 전달하면 하향 함수에서 props 이용해서 호출할 수 있게 된다
ExpenseForm.js
const submitHandler = (event) => {
event.preventDefault();
const expenseData = {
title: enteredTitle,
amount: enteredAmount,
date: new Date(enteredDate),
};
props.onSaveExpenseData(expenseData);
setEnteredTitle("");
setEnteredAmount("");
setEnteredDate("");
};
NewExpense.js
const NewExpense = (props) => {
const saveExpenseDataHandler = (enteredExpenseData) => {
const expenseData = {
...enteredExpenseData,
id: Math.random().toString(),
};
props.onAddExpense(expenseData); //여기서 전달하는 건 지출 데이터
};
return (
<div className="new-expense">
<ExpenseForm onSaveExpenseData={saveExpenseDataHandler} />
</div>
);
};
App.js
const addExpenseHandler = (expense) => {
console.log("In App.js");
console.log(expense);
};
return (
<div>
<NewExpense onAddExpense={addExpenseHandler} />
<Expenses items={expenses} />
</div>
);
};
export default App;
상태 위로 올리기
- 자식 컴포넌트에서 부모 컴포넌트로 데이터를 올리는 것
- 그것을 부모 컴포넌트에서 활용하거나 그 부모의 다른 자식 컴포넌트에게 전달할 수 있다
- 항상 최상위 컴포넌트로 전달하는 것이 아니라 필요한 곳까지 올려야 한다
- NewExpense 컴포넌트는 데이터랑 상태를 생성하는 컴포넌트로 사용자가 입력한 데이터를 가져오는 작업을 한다
- NewExpense 컴포넌트에 데이터를 저장하지 않고 대신 그 데이터를 App 컴포넌트로 보낸 후 App 컴포넌트에서 addExpenseHandler를 이용한다
파생/계산된 상태
- 먼저 새로운 상태를 정의하고 함수를 만들어줄 수 있지만 상태가 중복된다
- 대신 변수를 하나 추가하고 이 변수의 값을 동적으로 계산
- 설정하는 상태가 결국 다른 상태와 직접적으로 연결된다면 별도의 상태로 관리하는 건 좋지 않다
const [filteredYear, setFilteredYear] = useState('2020');
let filterInfoText = '2019, 2021 & 2022'; //계산된 값. 상태에서 파생된 값
if(filteredYear === '2019') {
filterInfoText = '2020, 2021 & 2022';
} else if (filteredYear === '2021') {
filterInfoText = '2019, 2020 & 2022';
} else {
filterInfoText = '2019, 2020 & 2021';
}
- 값이 상태로 관리되었던 게 아닌데도 년도대로 필터링이 된다
제어 컴포넌트 대 비제어 컴포넌트, 상태 비저장 컴포넌트 대 상태 저장 컴포넌트
- 값이랑 값에 발생하는 변경 작업은 컴포넌트 자체에서 처리하지 않고 부모 컴포넌트에서 처리한다
- 리액트 앱에서 상태를 관리하는 컴포넌트가 몇 개 있다
퀴즈
React로 작업 시 이벤트를 수신하지 않는 방법은?
- 수동으로 이벤트 리스너(ex) "addEventListner"를 통해)를 추가한다
onClick과 같은 이벤트 리스너 프로퍼티에는 어떤 값을 전달해야 하나요?
- 이벤트가 발생했을 때 실행해야 하는 함수의 포인터
- 실행될 함수의 '포인터'를 onClick 등의 값으로 전달하면 이벤트가 발생했을 때 '사용자를 대신하여' React가 함수를 실행한다
어떻게 하면 컴포넌트 중 하나에서 부모 컴포넌트, 즉 상위 수준으로 통신할 수 있나요?
- 프로퍼티를 통해 함수를 받아들이고 이를 하위 수준(자식) 컴포넌트 내부로부터 호출하고 해당 함수를 부모 컴포넌트에 전달하는 방식으로 일부 작업을 트리거 할 수 있다
컴포넌트가 화면에 표시하는 내용은 어떻게 변경할 수 있나요?
- useState를 통해 '상태'값을 생성해 JSX에서 변경 및 출력한다
변경 및 사용에 일반 JS 변수 대신 추가적인 '상태' 개념이 필요한 이유는 무엇인가요?
- 표준 JS 변수는 React 컴포넌트를 재평가하지 않기 때문이다
useState에 관한 설명으로 옳지 않은 것은 무엇인가요?
- useState를 다시 호출하면 상태 값이 업데이트된다
useState로 생성된 컴포넌트 상태는 어떻게 업데이트할 수 있나요?
- useState도 반환하는 상태 업데이트 함수를 호출한다
하나의 단일 컴포넌트로 얼마나 많은 상태를 관리할 수 있나요?
- 상태 slice를 필요하거나 원하는 만큼 가질 수 있다
const [counter, setCounter] = useState(1);
...
setCounter(counter + 1);
이 코드 조각에 무슨 문제가 있나요?
- 이전 상태에 의존하는 상태를 업데이트한다면, 상태 업데이트 함수의 '함수 양식'을 대신 사용해야 한다
'Frontend > React' 카테고리의 다른 글
[Udemy React 완벽 가이드] Section 6 (2) | 2024.01.04 |
---|---|
[Udemy React 완벽 가이드] Section 5 (2) | 2024.01.04 |
[Udemy React 완벽 가이드] Section 3 (1) | 2024.01.04 |
[Udemy React 완벽 가이드] Section 2 (3) | 2024.01.04 |
[Udemy React 완벽 가이드] Section 1 (1) | 2024.01.04 |