Apa hook di React?
Hooks adalah fitur baru yang ditambahkan di React v16.8. Hooks memungkinkan Anda untuk menggunakan semua fitur React tanpa menulis komponen kelas. Misalnya, sebelum versi 16.8, kita memerlukan komponen kelas untuk mengelola status komponen. Sekarang kita dapat menyimpan status dalam komponen fungsional menggunakan hook useState .
Akankah React hooks bekerja di dalam komponen kelas?
Tidak.
Mengapa hook diperkenalkan di React?
Salah satu alasan untuk memperkenalkan hook adalah sulitnya bekerja dengan kata kunci ini di dalam komponen kelas. Jika tidak ditangani dengan baik, ini akan memiliki arti yang sedikit berbeda. Ini akan memutus string seperti this.setState () dan penangan kejadian lainnya. Dengan menggunakan kait, kami menghindari kerumitan ini saat bekerja dengan komponen fungsional.
Komponen kelas tidak mengecil dengan baik dan juga membuat pemuatan ulang panas tidak dapat diandalkan. Ini adalah alasan lain untuk membuat pengait.
Alasan lainnya adalah bahwa tidak ada cara khusus untuk menggunakan kembali logika kacang yang stateful. Meskipun template HOC (Higher-Order Component) dan Render Props (metode meneruskan props dari induk ke anak menggunakan fungsi atau closure) memecahkan masalah ini, kode komponen kelas perlu diubah di sini. Hooks memungkinkan Anda untuk berbagi logika stateful tanpa mengubah hierarki komponen.
, . , (fetch) componentDidMount() componentDidUpdate(). : componentDidMount() componentWillUnmount() . .
useState? ?
useState - , . 2 . - . - .
useState React
import React, {useState} from "react";
useState, :
const [currentStateValue, functionToUpdateState] = useState(initialStateValue);
useState
. , , .
class Counter extends Component {
state = {
count: 0,
};
incrementCount = () => {
this.setState({
count: this.state.count + 1,
});
};
render() {
return (
<div>
<button onClick={this.incrementCount}>Count: {this.state.count}</button>
</div>
);
}
}
, React.
import React, { useState } from "react";
function Counter() {
const [count, setCount] = useState(0);
return (
<div>
<button
onClick={() => {
setCount(count + 1);
}}
>
Count: {count}
</button>
</div>
);
}
useState 2
. .
class Counter extends Component {
state = { count: 0 };
incrementCount = () => {
this.setState((prevState) => {
return {
count: prevState.count + 1,
};
});
};
decrementCount = () => {
this.setState((prevState) => {
return {
count: prevState.count - 1,
};
});
};
render() {
return (
<div>
<strong>Count: {this.state.count}</strong>
<button onClick={this.incrementCount}>Increment</button>
<button onClick={this.decrementCount}>Decrement</button>
</div>
);
}
}
, React.
.
, callback. callback- .
import React, { useState } from "react";
function Counter() {
const [count, setCount] = useState(0);
const incrementCount = () => {
setCount((prevCount) => {
return prevCount + 1;
});
};
const decrementCount = () => {
setCount((prevCount) => {
return prevCount - 1;
});
};
return (
<div>
<strong>Count: {count}</strong>
<button onClick={incrementCount}>Increment</button>
<button onClick={decrementCount}>Decrement</button>
</div>
);
}
useState 3
, , .
export class Profile extends Component {
state = {
name: "Backbencher",
age: 23,
};
onNameChange = (e) => {
this.setState({
name: e.target.value,
});
};
onAgeChange = (e) => {
this.setState({
age: e.target.value,
});
};
render() {
return (
<div>
<form>
<input
type="text"
value={this.state.name}
onChange={this.onNameChange}
/>
<input
type="number"
value={this.state.age}
onChange={this.onAgeChange}
/>
<h2>
Name: {this.state.name}, Age: {this.state.age}
</h2>
</form>
</div>
);
}
}
, React.
import React, { useState } from "react";
function Profile() {
const [profile, setProfile] = useState({
name: "Backbencher",
age: 23,
});
const onNameChange = (e) => {
setProfile({ ...profile, name: e.target.value });
};
const onAgeChange = (e) => {
setProfile({ ...profile, age: e.target.value });
};
return (
<div>
<form>
<input type="text" value={profile.name} onChange={onNameChange} />
<input type="text" value={profile.age} onChange={onAgeChange} />
<h2>
Name: {profile.name}, Age: {profile.age}
</h2>
</form>
</div>
);
}
useState() , . setState() .
spread JavaScript.
?
setState() . , , , , , .
, setState() . useState() spread .
useEffect?
useEffect . . .
useEffect
, Boom , .
export class Banner extends Component {
state = {
count: 0,
};
updateState = () => {
this.setState({
count: this.state.count + 1,
});
};
componentDidMount() {
console.log("Boom");
}
componentDidUpdate() {
console.log("Boom");
}
render() {
return (
<div>
<button onClick={this.updateState}>State: {this.state.count}</button>
</div>
);
}
}
console.log React.
.
componentDidMount() componentDidUpdate() - . useEffect. useEffect - , callback. callback , .
:
import React, { useState, useEffect } from "react";
function Banner() {
const [count, setCount] = useState(0);
useEffect(() => {
console.log("Boom");
});
const updateState = () => {
setCount(count + 1);
};
return (
<div>
<button onClick={updateState}>State: {count}</button>
</div>
);
}
useEffect 2
:
function Banner() {
const [count, setCount] = useState(0);
const [name, setName] = useState("");
useEffect(() => {
console.log(" ");
});
return (
<div>
<button onClick={() => setCount(count + 1)}>State: {count}</button>
<input
type="text"
value={name}
onChange={(e) => setName(e.target.value)}
/>
</div>
);
}
ยซ ยป . ?
.
useEffect , . props , . , , , . count .
useEffect:
useEffect(() => {
console.log("Count is updated");
}, [count]);
useEffect 3
, . componentDidMount() .
export class Clock extends Component {
state = {
date: new Date(),
};
componentDidMount() {
setInterval(() => {
this.setState({
date: new Date(),
});
}, 1000);
}
render() {
return <div>{this.state.date.toString()}</div>;
}
}
React.
.
componentDidMount() - , . useEffect, componentDidMount(). useEffect props . , - useState. . , React props, . , useEffect , componentDidMount().
React.
function Clock() {
const [date, setDate] = useState(new Date());
useEffect(() => {
setInterval(() => {
setDate(new Date());
}, 1000);
}, []);
return <div>{date.toString()}</div>;
}
useEffect 4
, .
componentDidMount() {
window.addEventListener("mousemove", this.handleMousePosition);
}
componentWillUnmount() {
window.removeEventListener("mousemove", this.handleMousePosition);
}
Tulis ulang kode ini dengan gaya kait React.
Keputusan.
Untuk menggunakan fungsionalitas metode siklus proses componentWillUnmount () dalam hook useEffect, Anda perlu mengembalikan callback dengan kode yang perlu dijalankan saat komponen dilepas.
useEffect(() => {
window.addEventListener("mousemove", handleMousePosition);
return () => {
window.removeEventListener("mousemove", handleMousePosition);
}
}, []);
Tugas menggunakan useContext
Berikut adalah potongan kode dari komponen Context.Consumer.
import { NameContext, AgeContext } from "./ProviderComponent";
export class ConsumerComponent extends Component {
render() {
return (
<NameContext.Consumer>
{(name) => {
return (
<AgeContext.Consumer>
{(age) => (
<div>
Name: {name}, Age: {age}
</div>
)}
</AgeContext.Consumer>
);
}}
</NameContext.Consumer>
);
}
}
Tulis ulang ConsumerComponent menggunakan hook useContext .
Solusi .
Hook hanya dapat digunakan dalam komponen fungsional.
ConsumerComponent dapat ditulis ulang seperti ini:
function ConsumerComponent() {
const name = useContext(NameContext);
const age = useContext(AgeContext);
return (
<div>
Name: {name}, Age: {age}
</div>
);
}