본문 바로가기
Front-end/React\RN

리액트 자식 대 부모 컴포넌트 통신

by javapp 자바앱 2022. 12. 8.
728x90

 

 

컴포넌트간 데이터 전달 실행

 

Form 에서 받은 데이터를 App.js 과 통신

 

 

App.js

import React from 'react';

import Expenses from './components/Expenses/Expenses';
import NewExpense from './components/NewExpense/NewExpense';

const App = () => {
  const addExpenseHandler = expense=>{
    console.log("in app.js")
    console.log(expense)
  }

  return (
    <div>
      <NewExpense onAddExpense={addExpenseHandler}/>
      <Expenses items={expenses} />
    </div>
  );
}

export default App;

NewExpense 컴포넌트를 import 하여 실행

<NewExpense onAddExpense={addExpenseHandler}/>

addExpenseHandler 를 통해 자식 컴포넌트의 데이터를 가져올 수 있음 

 


 

NewExpense.js

import React from 'react';
import ExpenseForm from './ExpenseForm';
import './NewExpense.css'
const NewExpense = (props) => {
    

    // 1.
    const addIdSaveExpenseDataHandler = (enteredExpenseData) =>{
        const expenseData = {
            ...enteredExpenseData,
            id: Math.random().toString()
        };
        // 4. app js
        props.onAddExpense(expenseData)
    }

    return (
        <div className='new-expense'>
            <ExpenseForm onSaveExpenseData={addIdSaveExpenseDataHandler}/>
        </div>
    );
};

export default NewExpense;

<ExpenseForm onSaveExpenseData={addIdSaveExpenseDataHandler}/>

    Form.js 에서 헨들러에 함수에 의해 실행되어 연관된 props.onAddExpense(expenseData) 실행

 

 

 

ExpenseForm.js

import React, { useState } from 'react';

import './ExpenseForm.css'

const ExpenseForm = (props) => {
    const [enteredTitle, setEnteredTitle] = useState('');
    const [enteredAmount, setEnteredAmount] = useState('');
    const [enteredDate, setEnteredDate] = useState('');
    
    
    // 가장 최신 상태의 스냅샷과 항상 계획된 상태업데이트 
    // 안전한 방법
    const titleChangeHandler=(event) =>{
        setEnteredTitle(event.target.value);
        // setUserInput((prevState) =>{
        //     return {...prevState,enteredTitle: event.target.value};
        // })
    }
    const amountChangeHandler=(event) =>{
        setEnteredAmount(event.target.value);
    }
    const dateChangeHandler=(event)=>{
        setEnteredDate(event.target.value)
    }

    const submitHandler =(event) =>{
        event.preventDefault();

        const expenseData ={
            title: enteredTitle,
            amount : enteredAmount,
            date: new Date(enteredDate)
        }

        // 2.
        props.onSaveExpenseData(expenseData)

        setEnteredTitle('');
        setEnteredAmount('');
        setEnteredDate('');
    };

    return (
        <form onSubmit={submitHandler}>
            <div className='new-expense__controls'>
                <div className='new-expense__control'>
                    <label>Title</label>
                    <input type="text" 
                    value={enteredTitle} onChange={titleChangeHandler} />
                </div>
                <div className='new-expense__control'>
                    <label>Amount</label>
                    <input type="text" 
                    value={enteredAmount} onChange={amountChangeHandler} min="0.01" step="0.01"/>
                </div>
                <div className='new-expense__control'>
                    <label>Date</label>
                    <input type="date" 
                    value={enteredDate} onChange={dateChangeHandler} min="2022-01-01" max="2022-12-31"/>
                </div>
            </div>
            <div className='new-expense__actions'>
                <button type="submit" >submit</button>
            </div>
        </form>
    );
};

export default ExpenseForm;

 

props.onSaveExpenseData(expenseData)

  form 에서 받은 데이터를 받아감

 

 

 

 

 

 

 

 


 

 

isEditing 에 따른 컴포넌트 제어

isEditing

 

 

import React, { useState } from 'react';
import ExpenseForm from './ExpenseForm';
import './NewExpense.css'

const NewExpense = (props) => {
    const [isEditing, setIsEditing] = useState(false)

    // 1.
    const addIdSaveExpenseDataHandler = (enteredExpenseData) =>{
        const expenseData = {
            ...enteredExpenseData,
            id: Math.random().toString()
        };
        // 4. app js
        props.onAddExpense(expenseData)
        // 제출후 실행
        setIsEditing(false);
    }

    const startEditingHandler = () =>{
        setIsEditing(true);
    }
    
    // 폼 핸들러에 전달
    const stopEditingHandler= () =>{
        setIsEditing(false);
    }
    
    return (
        <div className='new-expense'>
            {!isEditing && <button className="new-expense__actions" onClick={startEditingHandler}>Add new Expense</button>}
            {isEditing && <ExpenseForm 
                            onSaveExpenseData={addIdSaveExpenseDataHandler}
                            onCancel={stopEditingHandler}/>}
        </div>
    );
};

export default NewExpense;

  {!isEditing && <button className="new-expense__actions"

                                     onClick={startEditingHandler}>Add new Expense</button>}
  {isEditing && <ExpenseForm 
                            onSaveExpenseData={addIdSaveExpenseDataHandler}
                            onCancel={stopEditingHandler}/>}

 

ExpenseForm  에 onCancel 을 통해 isEditing 상태 전달

 

 

ExpenseForm.js

    <div className='new-expense__actions'>
        <button type="button" onClick={props.onCancel}>취소</button>
        <button type="submit" >submit</button>
    </div>

onClick={props.onCancel} 취소버튼 클릭시 isEditing = false가 되어 컴포넌트 조정

 

 

 

 

댓글