Một câu hỏi phổ biến mà các bạn React mới bắt đầu hay quan tâm là: “Làm thế nào để chia sẻ state giữa hai component anh em với nhau“. Câu trả lời là “đẩy state đó lên component cha” (lifting state) có nghĩa là bạn tìm một cha chung gần nhất cho hai component con đó và đặt state ở đó. Sau đó, truyền state xuống và áp dụng một số cách để state đã truyền xuống cho component con mỗi khi cần.
Lifting state
Bạn nhận được một feature mới là bạn phải hiển thị tên con vật mà người dùng nhập cho component Display
. Nhưng state của con vật đang được quản lý bởi một component anh em khác
. Bạn hãy tìm một component cha gần nhất để quản lí state đó và truyền props xuống cho Display
component.

import * as React from 'react'
function Name({name, onNameChange}) {
return (
<div>
<label htmlFor="name">Name: </label>
<input id="name" value={name} onChange={onNameChange} />
</div>
)
}
// 🐨 nhận `animal` and `onAnimalChange` props cho component này
function FavoriteAnimal() {
// 💣 xoá state này, bây giờ nó được quản lí bởi App
const [animal, setAnimal] = React.useState('')
return (
<div>
<label htmlFor="animal">Favorite Animal: </label>
<input
id="animal"
value={animal}
onChange={event => setAnimal(event.target.value)}
/>
</div>
)
}
// 🐨 bỏ comment cho component này
// function Display({name, animal}) {
// return <div>{`Hey ${name}, your favorite animal is: ${animal}!`}</div>
// }
// 💣 xoá component này
function Display({name}) {
return <div>{`Hey ${name}, you are great!`}</div>
}
function App() {
// 🐨 thêm useState để quản lí animal
const [name, setName] = React.useState('')
return (
<form>
<Name name={name} onNameChange={event => setName(event.target.value)} />
{/* 🐨 truyền animal and onAnimalChange prop (similar to the Name component above) */}
<FavoriteAnimal />
{/* 🐨 truyền the animal prop here */}
<Display name={name} />
</form>
)
}
export default App
Đáp án:
import * as React from 'react'
function Name({name, onNameChange}) {
return (
<div>
<label htmlFor="name">Name: </label>
<input id="name" value={name} onChange={onNameChange} />
</div>
)
}
function FavoriteAnimal({animal, onAnimalChange}) {
return (
<div>
<label htmlFor="animal">Favorite Animal: </label>
<input id="animal" value={animal} onChange={onAnimalChange} />
</div>
)
}
function Display({name, animal}) {
return <div>{`Hey ${name}, your favorite animal is: ${animal}!`}</div>
}
function App() {
const [animal, setAnimal] = React.useState('')
const [name, setName] = React.useState('')
return (
<form>
<Name name={name} onNameChange={event => setName(event.target.value)} />
<FavoriteAnimal
animal={animal}
onAnimalChange={event => setAnimal(event.target.value)}
/>
<Display name={name} animal={animal} />
</form>
)
}
export default App
Liên kết state và component(Collocating state)
Bây giờ bạn hiểu rõ về lifting state và khi bạn quen dần với cách này bạn sẽ nhanh chóng tổ chức state của bạn được tốt nhất trong app. Nhưng có một kỹ thuật khác, nghe có vẻ trái ngược với lifting state là pushing state back down(di chuyển state xuống dưới những component phù hợp)
Bạn nhận được một feature là trong component Display
chúng ta chỉ cần hiển thị animal
, không cần name
prop nữa.
Component <Display /> chỉ nhận một prop như sau:
function Display({animal}) {
return <div>{`Your favorite animal is: ${animal}!`}</div>
}
Do đó bạn phải di chuyển state của name xuống component Name
.
Kết quả như thế này:
import * as React from 'react'
function Name() {
const [name, setName] = React.useState('')
return (
<div>
<label htmlFor="name">Name: </label>
<input
id="name"
value={name}
onChange={event => setName(event.target.value)}
/>
</div>
)
}
function FavoriteAnimal({animal, onAnimalChange}) {
return (
<div>
<label htmlFor="animal">Favorite Animal: </label>
<input id="animal" value={animal} onChange={onAnimalChange} />
</div>
)
}
function Display({animal}) {
return <div>{`Your favorite animal is: ${animal}!`}</div>
}
function App() {
const [animal, setAnimal] = React.useState('')
return (
<form>
<Name />
<FavoriteAnimal
animal={animal}
onAnimalChange={event => setAnimal(event.target.value)}
/>
<Display animal={animal} />
</form>
)
}
export default App
thaunguyen.com via Epic React by Kent C.Dodds
Tự học ReactJS: Sử dụng useContext - Thau Nguyen
[…] component là bài toán phổ biến trong React app. Giải pháp tốt nhất là bạn phải lifting state. Nhưng nó yêu cầu bạn phải truyền props xuống cho các component con. Điều đó […]
ReactJS: Quản lý server state với react-query - Thau Nguyen
[…] đến một số em hot như Redux, React Context, Mobx, … đến các khái niệm như lifting state, collocation state, local state, global […]