刚学习 React 的时候,一定会碰到一个小问题,就是当我们有个值需要存在在两个元件之间,该怎麽处理? 而这个问题的答案很简单就是将 State 提升,今天就让我们来学习这个概念吧!
假设今天有个需求是要做一个 BMI 计算功能。画面需要有两个 input 分别接收身高与体重与一个按钮,按下按钮会跑出 alert 视窗并显示 BMI。
import { useState } from 'react'
function calculateBMI({ height, weight }){
if (!Number(height)) return NaN
const heightNum = Number(height) / 100
const weightNum = Number(weight)
const result = weightNum / (heightNum * heightNum)
return result.toFixed(2)
}
function BMIform(){
const [ bodyInfo, setBodyInfo ] = useState({
height: '',
weight: ''
})
const { height, weight } = bodyInfo
const onChangeHandler = (e) => {
const { name, value } = e.target
setBodyInfo(prev => ({...prev, [name]: value }))
}
const onSubmitHandler = (e) => {
e.preventDefault()
const result = calculateBMI(bodyInfo)
const text = isNaN(result) ? '请输入正确的身高与体重' : `您的 BMI 为:${result}`
alert(text)
}
return(
<form onSubmit={onSubmitHandler}>
<label>
身高(公分):
<input name='height' value={height} onChange={onChangeHandler}/>
</label>
<label>
体重(公斤):
<input name='weight' value={weight} onChange={onChangeHandler}/>
</label>
<button>计算</button>
</form>
)
}
function App() {
return (
<div className="App">
<BMIform />
<Display type='BMI' value={}/>
</div>
)
}
export default App
顺利的话当我们输入正确的身高与体重,按下计算,会成功跳出 alert 来。
接下来假设拿到了需求变更,用 alert 觉得不太好,想要改成在下方显示 BMI。然後我们已经有一个 Display 的元件,但需要传入 type 与 value 才能显示。
function Display({ type, value }){
return(
<div>
您的 {type} 为: {value}
</div>
)
}
function App() {
return (
<div className="App">
<BMIform />
<Display type="BMI" />
</div>
)
}
这个时候我们必须把 state 从 BMIform 元件中提升到 App 元件,也就是共用 state 的两个元件最近的父层元件。将 state 提升後,在分别将 state 作为两个元件 props 传递下去。所以我们可以将范例改成这样:
function BMIform({ bodyInfo, onBMIChange }){
const { height, weight } = bodyInfo
return(
<form>
<label>
身高(公分):
<input name='height' value={height} onChange={onBMIChange}/>
</label>
<label>
体重(公斤):
<input name='weight' value={weight} onChange={onBMIChange}/>
</label>
</form>
)
}
function Display({ type = 'BMI', value = null }){
return(
<div>
您的 { type } 为: {value}
</div>
)
}
function App() {
const [ bodyInfo, setBodyInfo ] = useState({
height: '',
weight: ''
})
const result = calculateBMI(bodyInfo)
const onBMIChange = (e) => {
const { name, value } = e.target
setBodyInfo(prev => ({ ...prev, [name]: value }))
}
return (
<div className="App">
<BMIform bodyInfo={bodyInfo} onBMIChange={onBMIChange}/>
{ isNaN(result) ? '请输入正确的身高与体重' : <Display type='BMI' value={result}/> }
</div>
)
}
export default App
透过将共享的 state 提升到最靠近它们的共同父层,能够确保两个元件的资料来源都是通一份,并且保持同步。以上就是今天关於提升 state 的练习与介绍。有问题都欢迎在下方留言。
该文章同步发布於:我的部落格
>>: Day 29 - Android Studio 这几天以来的统整
最後一篇,想说讲一下最近很夯的NFT,做为一个结尾。 NFT Non-Fungible Token,...
学习「怎样学习」 大纲 学习能力 软技能:代码之外的生存指南 十步学习法「概述」 第一部分:「研究」...
StatefulWidget 的build 回到昨天 StatefulWidget 的 build ...
谈到扩充性,JUCE 以 Modules 为基础,开发者可提供自制 Module,供其他人使用。如下...
Problem: 118. Pascal's Triangle(Easy) Pascal's Tri...