React)サブ構成部品ステータスから親構成部品=Lifting State Up

15417 ワード

(サブ方向)ExpenseForm=>NewExpense=>App.js(親方向)
ExpenseForm => NewExpense
元々は、サブコンポーネントに関数を作成し、親コンポーネントによって作成し、propsとしてサブコンポーネントに送り、サブコンポーネントから派生したstate(データ)を親コンポーネントから得られる関数のパラメータとして受け入れていた.
コアは、親コンポーネントで作成された関数を子コンポーネントに降格することです.
//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;
//NewExpense.js
import React from 'react';
import "./NewExpense.css";


import ExpenseForm from './ExpenseForm';

const saveExpenseDataHandler = ( enteredExpenseData )=> {
    const expenseData ={
        ...enteredExpenseData,
        id:Math.random().toString()
    };
    console.log(expenseData);
};

const NewExpense = () => {
    return (
        <div className="new-expense">
           <ExpenseForm onSaveExpenseData = { saveExpenseDataHandler } />
        </div>
    );
};

export default NewExpense;
//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);
    };
    const amountChangeHandler = (e)=> {
        setEnteredAmount(e.target.value);
    };
    const dateChangeHandler = (e)=> {
        setEnteredDate(e.target.value);
    };
    const submitHandler=(event)=>{
        event.preventDefault();

        const expenseData = {
            title: enteredTitle,
            amount: enteredAmount,
            date: new Date(enteredDate),
        }
        props.onSaveExpenseData();
        
        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="number" min="10" step="10" value={enteredAmount} onChange={amountChangeHandler}/>
                </div>
                <div className="new-expense__control">
                    <label>Date</label>
                    <input type="date" min="2019-01-01" max="2022-12-31" value={enteredDate} onChange={dateChangeHandler}/>
                </div>
           </div>
           <div className="new-expense__actions">
               <button type="submit">Add Expense</button>
           </div>
       </form>
    );
};

export default ExpenseForm;
NewExpense => App.js
  • App.jsコンポーネントの関数
  • を作成

  • //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),
        },
      ];
    
      const addExpenseHandler = (expense)=> {
        console.log('in app.js');
        console.log(expense);
      }
    
      return (
        <div>
          <NewExpense onAddExpense = { addExpenseHandler }/>
          <Expenses items={expenses}/>
        </div>
      );
    };
    
    export default App;
    
    //NewExpense.js
    
    import React from "react";
    import "./NewExpense.css";
    import ExpenseForm from "./ExpenseForm";
    
    const NewExpense = (props) => {
    
      const saveExpenseDataHandler = (enteredExpenseData) => {
        const expenseData = {
          ...enteredExpenseData,
          id: Math.random().toString(),
        };
        자식 컴포넌트에서 생긴 데이터를 부모 컴포넌트에서 프롭스로 받은 function에 parameter로 넘겨준다.
        props.onAddExpense(expenseData);
      };
    
      return (
        <div className="new-expense">
          <ExpenseForm onSaveExpenseData={saveExpenseDataHandler} />
        </div>
      );
    };
    
    export default NewExpense;