Dealing with Events, useState

김민경·2023년 1월 28일
0

FE(WEB) - React

목록 보기
4/13

Dealing with Events

  • uses on~(the name of the event)
<button onClick = {() => {console.log("something")}> Change Title </button>
const clickHandler = () => {
	console.log('Clicked!!!');
};
<button onClick = ⭐{clickHandler}> Change Title </button>

// ⭐onClick = {clickHandler()} (x)
// -> executes it as the HTML codes are rendered

pass a pointer at this function as a value to onClick
and then React basically memorizes this

How does component works?

=> only changes the modified DOM element

useState

React doesnt' re-render the modified value
if the value is pronounced with keyword such as 'let'.
Instead, it re-renders the modified value
when dealing with the "state" value
.

Here, we use useState hook to manage the value with state.

const [presentState, setPresentState] = useState(initial value)
// useState() returns a array with two elements
// [the value itself, and the updating function]
// initial value is only meaningful when the component is rendered for the first time
  • when the setPresentState function is called, it re-renders the very component function it is belonged to.

  • when the setPresentState is called,
    it doesn't immediately updates the state
    but schedules the update

    -> therefore when you track the value by console.log() right after calling the setPresentState, it shows the previous value

  • we use const key-word because we are not using equal sign(=) when updating a value

Dealing with Form Datas

(dealing with event 객체)

const titleChangeHandler = (e) => {
	console.log(e.target.value);
};

return (
	<form>
    	<input type='text' onChange = {titleChangeHandler}
    </form>
)

if there are several states to manage

  • (method 1) managing severel states seperately
const [enteredTitle, setEnteredTitle] = useState('');
const [enteredAmount, setEnteredAmount] = useState('');
const [enteredDate, setEnteredDate] = useState('');

const titleChangeHandler = (e) => {
	setEnteredTitle(e.target.value)
}
// ... same with setEnteredAmount, setEnteredDate
  • (method 2) managing severel states wholey

(+ ❗what should be done whenever state update depends on the previous state)

const [userInput, setUserInput] = useState({
	enteredTitle : '',
    enteredAmount : '',
   	enteredDate : ''
});

const titleChangeHandler = (e) => {
	// setUserInput ({
    // 	...userInput,
    // 	enteredTitle : e.target.value, 
    // })
    // this isn't a good apporach (has a possibility to trigger bugs)
    
    // it is because React schedules state updates,
    // it doesn't perform them istantly
    // so if you schedule a lot of state updates at the same time,
    // could be depending on an outdated or incorrect state snapshot
    
    // therefore, should call it and pass in a function to the very function
    setUserInput((prevState) => {
    	return {...prevState, enteredTitle : e.target.value };
    });
    // in this way, React will guarantee 
    // that the prevState it gives in this inner function
    // will always be the latest state snapshot,
    // keeping all scheduled state updates in mind
    // it ensures that it is working on the latest state snapshot
    
    // so whenever state update depends on the previous state,
    // the code should be written by this way
}

(ex - what should be done whenever state update depends on the previous state)

틀린 예시

const [counter, setCounter] = useState(1);
...
setCounter(counter + 1);

맞는 예시

const [counter, setCounter] = useState(1);
...
setCounter ((prevState) => 
	return (prevState+1);
);

submitting a data

  • e.preventDefault()
  • two-way binding
const [enteredTitle, setEnteredTitle] = useState('');

const submitHandler = (e) => {
	e.preventDefault();
    // a part of the default browser behavior
    // is that if the button is clicked, the page is reloaded,
    
    // because the browser actually automatically sends a request
    // whenver the form is submitted to the server which is hoisting the webpage
    
    // two-way binding : 
    // for inputs, we not only listen to changes 
    // but also pass a new value back into the input
    // so that we can reset or change the input programmatically
    setEnteredTitle('')
    
};

return (
	<form onSubmit = {submitHandler}>
    	<input type = 'text' ⭐value={enteredTitle} 
        ⭐onChange = {titleChangeHandler}/>
    </form>
)

return (
	<form onSubmit = {submitHadler}>
    	// the content
        <button type="submit"> Add Expense </button>
    </form>
)

Sharing States(upwards)

(child component -> parent component)(상향식으로)

=> 프로퍼티를 통해 함수를 받아들이고
이를 하위 수준(자식) 컴포턴트 내부로부터 호출하고
해당 함수를 부모 컴포넌트에 전달하는 방식

(Terms)

  • stateless/dumb components
    : component that manages some states
  • stateful/smart component
    : the opposite

(Ex.1)

parent-parent component(App.js)

const addExpenseHandler = expense => {
	console.log('Im App.js');
    console.log(expense);
};

return (
	<div>
    	<NewExpenses ⭐onAddExpense = {addExpenseHandler}/>
    </div>
)

parent component(NewExpense.js)


const saveExpenseDataHancler = (enteredExpenseData) => {
	const expenseData = {
    	...enteredExpenseData,
        // use spread operator for 얕은 복사
        id : Math.random().toString()
    };
    ⭐props.onAddExpense(expenseData);
};

return (
	<div>
    	<ExpenseForm ⭐onSaveExpenseData = {saveExpenseDatahandler} />
    </div>

child component(ExpenseForm.js)

const submitHandler = (e) => {
	e.preventDefault();
    
    const expenseData = {
    	title : enteredTitle,
    };
    
    ⭐props.onSaveExpenseData(expenseData);
    
    setEnteredTitle('');
}

(Ex.2)

parent component(Expenses.js)

const [filteredYear, setFilteredYear = useState('2020');

const filterChangeHandler = selectedYear => {
	setFilteredYear(selectedYear);
};

return (
	<ExpensesFilter ⭐selected = {filteredYear} 
    ⭐onChangeFilter = {filterChangeHandler} />

child component(ExpensesFilter.js)

const ExpensesFilter = (props) => {
  const dropdownChangeHandler = (event) => {
    ⭐props.onChangeFilter(event.target.value);
  };

  return (
    <div className='expenses-filter'>
      <div className='expenses-filter__control'>
        <label>Filter by year</label>
        <select ⭐value={props.selected} onChange={dropdownChangeHandler}>
          <option value='2022'>2022</option>
          <option value='2021'>2021</option>
          <option value='2020'>2020</option>
          <option value='2019'>2019</option>
        </select>
      </div>
    </div>
  );
};
profile
🏛️❄💻😻🏠

0개의 댓글