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>
);
}
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.
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
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.
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
you can call multiple states per component.
(my preferred method)
const [enteredTitle, setEnteredTitle] = useState("");
const [enteredAmount, setEnteredAmount] = useState("");
const [enteredDate, setEnteredDate] = useState("");
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}
/>
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
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>
);
.
.
.
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