状态晋升
在 React 利用中,任何可变数据该当只有一个绝对应的惟一的‘数据源’,通常 state 都是首先增加到须要渲染数据的组件中去,而后,如果其余组件也须要这个 state,那么能够 将其晋升至这些组件的独特父组件中
比方想要实现这么一个例子:想要摄氏温度输入框与华氏度的输入框的数据同步更改,并且当摄氏水温大于 100 时会给出水会沸腾的提醒语,反之则是水不会沸腾
show you the code
在这个例子中,因为摄氏温度输入框与华氏度的输入框须要同步,因而将这两个组件须要共享的 state 向上挪动到其最近的独特父组件中,因为两个 TemperatureInput 组件的 props 均来自独特的父组件 Calculator,因而两个输入框中的内容将始终保持统一。同时如果某些数据能够由 props 或 state 推导得出,那么它就不应该存在于 state 中,比方这个例子中的 celsiusValue 和 fahrenheitValue
function Calculator(){const [temperature, setTemperature] = useState<string>('')
const [scale, setScale] = useState<string>('c')
const toCelsius = useCallback((fahrenheit)=>{return (fahrenheit - 32) * 5 / 9;
},[])
const toFahrenheit = useCallback((celsius)=>{return (celsius * 9 / 5) + 32;
},[])
const tryConvert = useCallback((temperature, convert)=>{const input = parseFloat(temperature);
if (Number.isNaN(input)) {return '';}
const output = convert(input);
const rounded = Math.round(output * 1000) / 1000;
return rounded.toString();},[])
const getRightTemperature = useCallback(()=>{const celsius = scale === 'f' ? tryConvert(temperature, toCelsius) : temperature;
const fahrenheit = scale === 'c' ? tryConvert(temperature, toFahrenheit) : temperature;
return {
celsius,
fahrenheit,
}
},[temperature,scale])
const handleCTempChange = useCallback((val)=>{setScale('c')
setTemperature(val)
},[])
const handleFTempChange = useCallback((val)=>{setScale('f')
setTemperature(val)
},[])
return(
<>
<TemperatureInput scale='c' temperature={getRightTemperature().celsius} onTempChange={handleCTempChange}/>
<TemperatureInput scale='f' temperature={getRightTemperature().fahrenheit} onTempChange={handleFTempChange}/>
<BoilingVerdict celsius={parseFloat(getRightTemperature().celsius))}/>
</>
)
}
interface ITprops{
scale: 'c' | 'f',
temperature:string,
onTempChange:(val:string)=>void
}
function TemperatureInput(props:ITprops){
const scaleNames = {
c: 'Celsius',
f: 'Fahrenheit'
};
return(
<fieldset>
<legend>Enter temperature in {scaleNames[props.scale]}:</legend>
<input value={props.temperature} onChange={(e)=>props.onTempChange(e.target.value)}></input>
</fieldset>
)
}
interface IBprops{celsius:number}
function BoilingVerdict(props:IBprops){if (props.celsius >= 100) {return <p>The water would boil.</p>;}
return <p>The water would not boil.</p>;
}
React 哲学
组合 VS 继承:在 react 中并没有发现须要应用继承来构建组件档次的状况,props 和组合提供清晰而平安地定制组件外观和行为的灵便形式,组件能够承受任意 props,包含根本数据类型,React 元素以及函数,如果想要在组件间复用非 UI 的性能,能够将其提取伟一个独自的 JS 模块
如何构建一个利用:
划分组件层级 (繁多性能准则) –> 创立一个动态页面(自上而下或者自下而上) –> 确定 state 的最小(且残缺) 示意(DRY) –> 确定 state 的地位(是否须要状态晋升) –> 增加反向数据流(回调函数传递)
DRY: Don’t Repeat Yourself, 只保留利用所需的可变 state 的最小汇合,其余数据均由它们计算产生。