React.js note #3

Yechan Jeon·2021년 12월 18일
0

React dev

목록 보기
3/18
post-thumbnail

React State & Working with Events


Goal: Learning concepts for making an app intercative & reactive

How to listen to events?

To add event listener, we can add some props in JSX element.
It starts with 'on' and Like we always do in vanilla js, it is also need function to execute event as prop value.

<button
        onClick={() => {
          console.log("clicked");
        }}
      >
        Change Title
</button>

And Actually you'd better put the functions outside and use it for prop values. Code below is much better approach

function ExpenseItem(props) {
  const clickEvent = () => {
    console.log("clicked");
  };

  return (
    <Card className="expense-item">
      <button onClick={clickEvent}>Change Title</button>
    </Card>
  );
}

How component function are executed?

React execute every functions until there's no more component code left to call (custom HTML elements also regarded as function)
But the problem is that react doesn't repeat this steps.
So we need a way to convey changes and tell react that some values need to be re-evaluated again. The solution is state.

React State

Import useState function from react packages and invoke it in function (you should invoke state function in component function)

import React, { useState } from "react";
function ExpenseItem(props) {
  let title = props.title;
  useState();
  .
  .
  
 }

Instead of assignment to change value, we can change value with function from state by setting initial state in parenthesis

const [title, setTitle] = useState(props.title);

state returns array, so we can destructure it.
Then, you can invoke function and put a parameter value which you want to change

const [title, setTitle] = useState(props.title);

  const clickEvent = () => {
    setTitle('Updated!');
    console.log(title);
  };

By invoking functions to change a value, component function will be executed again
In conclustion, you can change a value and let react evalute the value again as you use state

useState() detail

  1. use state register some states.
    More precisely, it registers a component instance
    Every time it is called, it generate each instances and it is mananged independently by react.
    As a result, even though we use one component several times, there is no dependence between these components.

  2. why we use const though we assign value
    Actually we didn't assign value with equal sign.
    When the functions executed again, the state assignment is also invoked again.
    So It doesn't mean we fix the value in constant, it means we just take a value from state array

  3. you can call multiple states per component.
    (my preferred method)

  const [enteredTitle, setEnteredTitle] = useState("");
  const [enteredAmount, setEnteredAmount] = useState("");
  const [enteredDate, setEnteredDate] = useState("");
  1. Also you can combine all states as one.
  const [userInput, setUserInput] = useState({
    title: "",
    amount: "",
    date: "",
  });

  const titleChangeHandler = (evt) => {
    setUserInput((prevState) => {
      return { ...prevState, title: evt.target.value };
    });
  };

  const amountChangeHandler = (evt) => {
    setUserInput((prevState) => {
      return { ...prevState, amount: evt.target.value };
    });
  };

  const dateChangeHandler = (evt) => {
    setUserInput((prevState) => {
      return { ...prevState, date: evt.target.value };
    });
  };

Be sure to spread previous state if the states depend on it. Because react doens't merge changes, but it just replace old things, if you don't clarify other elements state, it will be removed.
5. You can bind the changes in input

<input
  type="text"
  value={enteredTitle}
  onChange={titleChangeHandler}
/>

Child to parent component communication(Lifting state up)

For example with form, we can make our own props.

First, make a event handler props in your parent component.
Second, Build a logic for that event handler but do not execute with parenthesis in prop value.
Third, In your child component, Use that handler prop property and save the form data in that handler

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

  return (
    <div className="new-expense">
      <ExpesneForm onSaveExpenseData={saveExpenseDataHandler}></ExpesneForm> //<-check this
    </div>
  );
  • Child
.
.
.
const submitHandler = (evt) => {
    evt.preventDefault();
    const expenseData = {
      title: enteredTitle,
      amount: enteredAmount,
      date: new Date(enteredDate),
    };
    props.onSaveExpenseData(expenseData); //<-check this
    setEnteredTitle("");
    setEnteredAmount("");
    setEnteredDate("");
  };
.
.
.

we can summarize this process like this.
1. parent -> props(handler) -> child
2. child -> get props(handler) -> set data in that props -> parent

[Terms]
Stateless, dumb, presentational component : a component which doens't have any internal component (you will have this kind of components more in your react app.)

Stateful, smart : Exactly opposite of above term

Ref : React - The complete guide

profile
방황했습니다. 다시 웹 개발 하려고요!

0개의 댓글