Exepense의 데이터를 App 컴포넌트에 전달하고자 합니다.
부모 컴포넌트가 app이고 자식 컴포넌트가 Expense이므로 역방향으로 데이터를 전달하는 것입니다.
<input type="text" value={enteredTitle} onChange={titleChangeHandler}/>
prop으로 함수가 필요한 onChange 메소드는 event listener가 설정된 함수를 받는 패턴으로 작동됩니다.
이 패턴은 컴포넌트에서도 가능합니다.
부모 컴포넌트에서 자식 컴포넌트로 함수를 전달 해 줄 것이고, 자식 컴포넌트에서 함수를 호출합니다.
그리고 그 함수에 매개변수로 데이터를 전달하게 해 줍니다.
이런식으로 자식에서 부모로 정보를 전달할 수 있습니다.
오직 직계 부모<->자식간의 컴포넌트만 정보 전달이 가능합니다
건너뛰기 불가능
/*NewExpense.js*/
<ExpenseForm onSaveExpenseData></ExpenseForm>
우선 첫번째 부모컴포넌트인 NewExpense.js에서 호출하고있는 ExpenseForm에 onSaveExpenseData를 넣어줍니다.
이 함수는 JSX코드를 반환하기 전에 NewExpense컴포넌트에 정의되어야 합니다.
/*NewExpense.js*/
function NewExpense() {
const saveExpenseDataHandler = (enteredExpenseData)=>{
const expenseData = {
...enteredExpenseData,
id:Math.random().toString(),
};
console.log(expenseData);
}
return (
<div className='new-expense'>
<ExpenseForm onSaveExpenseData={saveExpenseDataHandler}></ExpenseForm>
</div>
)
}
saveExpenseDataHandler라는 함수를 선언해줍니다.
이 함수는 enteredExpenseData라는 값을 props로 받고
JSX에서는 onSaveExpenseData의 속성값은 saveExpenseDataHandler로 받습니다.
쉽게말해 함수 실행이 아닌 함수를 가리키는 것입니다.
이 함수는 ExpenseForm으로 전달됩니다.
이제 ExpenseForm 안에는 onSaveExpenseData속성이 있습니다.
function ExpenseForm(props)
컴포넌트 함수 props부분에 값을 넣어줍니다.
이제 props안에는 NewExpense.js에서 설정한 값인 onSaveExpenseData속성이 있습니다.
props.onSaveExpenseData()
onSaveExpenseData는 함수를 가져왔기 때문에 실행시킬 수 있습니다.
실행시키면 NewExpense에서 선언한 함수가 ExpenseForm에서 실행이됩니다.
const submitHandler=(event)=>{
event.preventDefault();
const expenseData = {
title:enteredTitle,
amount:enteredAmount,
date:new Date(enteredDate)
};
props.onSaveExpenseData(expenseData);
}
결국 최종적으로 이벤트리스너를 props로 받아 제출 시 실행하는 함수인 submitHandler가
expenseData를 onSaveExpenseData의 매개변수로 넣어줍니다.
어떻게 매개변수를 받을 수 있냐면
function NewExpense() {
const saveExpenseDataHandler = (enteredExpenseData)=>{
const expenseData = {
...enteredExpenseData,
id:Math.random().toString(),
};
console.log(expenseData);
}
return (
<div className='new-expense'>
<ExpenseForm onSaveExpenseData={saveExpenseDataHandler}></ExpenseForm>
</div>
)
}
NewExpense.js에서 매개변수를 받는 함수인 saveExpenseDataHandler를 onSaveExpenseData가 가르키고 있기 때문입니다.
그럼 이렇게 저희가 랜덤시드값으로 설정한 id가 콘솔에 출력되게 됩니다.
자식 컴포넌트에서 실행한걸 부모 컴포넌트가 받는 느낌입니다.
이제 가장 최상위컴포넌트인 app.js에 전달하겠습니다.
/* app.js*/
const addExpenseHandler = (expense)=>{
console.log('App.js');
console.log(expenses);
}
return (
<div>
<NewExpense onAddExpense={addExpenseHandler}></NewExpense>
<Expense items={expenses}></Expense>
</div>
);
/* NewExpense.js */
function NewExpense(props) {
const saveExpenseDataHandler = (enteredExpenseData)=>{
const expenseData = {
...enteredExpenseData,
id:Math.random().toString(),
};
props.onAddExpense(expenseData);
}
실행해보면 app.js에서 랜덤시드값을 가진 새로운 객체가 출력되는 것을 볼 수 있습니다.