10. react - 状态提升
1. 什么是状态提升:
状态提升是指,公共父组件统一管理子组件状态的过程。
2. 为什么要做状态提升:
当两个子组件渲染同一个数据的不同状态时,并且要求两个子组件数据同步变化,子组件之间不能相互作用,这时,就需要提升到公共父组件处理要渲染的数据。
例如:官网 摄氏度和华氏度控制水沸腾的例子
3. 数据流向:
状态管理组件(父组件) 通过 【属性绑定】 状态 和 改变状态的方法
子组件通过 props 获取数据和父组件的方法,通过 this.props 渲染数据,调用方法。
/*数据处理的公共方法*/ function toCelsius(fahrenheit) { return (fahrenheit - 32) * 5 / 9; } function toFahrenheit(celsius) { return (celsius * 9 / 5) + 32; } function tryConvert(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 scaleNames = { c: 'Celsius', f: 'Fahrenheit' }; // 1. 抽离温度显示组件 class TemperatureInput extends React.Component{ constructor (props) { super(props) this.handleChangeT = this.handleChangeT.bind(this) this.inputRef = React.createRef() } // 通过事件触发父组件的方法 handleChangeT (e) { console.log(this.inputRef) // 通过props触发父组件的方法 this.props.onTemperatureChange(this.inputRef.current.value) } render () { const temperature = this.props.temperature return ( <fieldset> {this.props.type === 'c' ? <legend>请输入摄氏度</legend> : <legend>请输入华氏度</legend>} <input value={temperature} onChange={this.handleChangeT} ref={this.inputRef} /> </fieldset> ) } } // 抽取 Calculator 组件, 管理状态 class Calculator extends React.Component { constructor (props) { super(props) this.state = { temperature: '', type: 'c' } this.calcC = this.calcC.bind(this) this.calcF = this.calcF.bind(this) } calcC (temperature) { this.setState({ temperature, type: 'c' }) } calcF (temperature) { this.setState({ temperature, type: 'f' }) } render() { // 计算摄氏度,华氏度 fahrenheit const temperature = this.state.temperature const fahrenheit = this.state.type === 'c' ? tryConvert(temperature, toFahrenheit) : temperature const celsius = this.state.type === 'f' ? tryConvert(temperature, toCelsius) : temperature return (
// onTemperatureChange属性传递方法给子组件 <div> <TemperatureInput type="c" onTemperatureChange={this.calcC} temperature={celsius} /> <TemperatureInput type="f" onTemperatureChange={this.calcF} temperature={fahrenheit} /> {celsius >= 100 ? <h2>水沸腾了</h2> : <h2>水还没开</h2>} </div> ) } } ReactDOM.render( <Calculator />, document.getElementById('root') )
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 理解Rust引用及其生命周期标识(上)
· 浏览器原生「磁吸」效果!Anchor Positioning 锚点定位神器解析
· 没有源码,如何修改代码逻辑?
· 分享4款.NET开源、免费、实用的商城系统
· 全程不用写代码,我用AI程序员写了一个飞机大战
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了
· 上周热点回顾(2.24-3.2)