React学习之最近公共组件(九)
经常,我们会遇到多个组件使用同一个数据,那时候我们就需要消除掉每一个组件中的数据,而构造出一个公共的祖先组件来处理。 我将以一个温度测试组件来进行演示
function BoilingVerdict(props) {
if (props.celsius >= 100) {
return <p>The water would boil.</p>;
}
return <p>The water would not boil.</p>;
}
class Calculator extends React.Component {
constructor(props) {
super(props);
this.handleChange = this.handleChange.bind(this);
this.state = {temperature: ''};
}
handleChange(e) {
this.setState({temperature: e.target.value});
}
render() {
const temperature = this.state.temperature;
return (
<fieldset>
<legend>Enter temperature in Celsius:</legend>
<input
value={temperature}
onChange={this.handleChange} />
<BoilingVerdict
celsius={parseFloat(temperature)} />
</fieldset>
);
}
}
增加另外一个输入,之前是摄氏度,这里是华氏度,当然他们是同步的
const scaleNames = {
c: 'Celsius',f: 'Fahrenheit'
};
class TemperatureInput extends React.Component {
constructor(props) {
super(props);
this.handleChange = this.handleChange.bind(this);
this.state = {temperature: ''};
}
handleChange(e) {
this.setState({temperature: e.target.value});
}
render() {
const temperature = this.state.temperature;
const scale = this.props.scale;
return (
<fieldset>
<legend>Enter temperature in {scaleNames[scale]}:</legend>
<input value={temperature}
onChange={this.handleChange} />
</fieldset>
);
}
}
class Calculator extends React.Component {
render() {
return (
<div>
<TemperatureInput scale="c" />
<TemperatureInput scale="f" />
</div>
);
}
}
上述代码很明显是实现不了的,因为每一个组件都只控制了自己内部的元素没有事受外部影响,何来同步一说。 之前我就说过数据的单向性,只能父组件控制子组件,并且这个控制还是基于子组件的接口而定的,除此之外,外部所有的组件都无法直接与子组件相连接,无法互相处理。 那么唯一能够用到就是基于父组件了,既然无法直接相处理,那么我们就通过他们的公共父组件相连接,这里的公共父组件一般为最近公共祖先组件,所谓的公共祖先组件在算法上的理解就是二叉树两个节点之间的最近公共祖先节点。 那么我们的代码就可以变为如下: //其中省略了部分代码,希望大家自己完成补充实现响应的功能
class TemperatureInput extends React.Component {
constructor(props) {
super(props);
this.handleChange = this.handleChange.bind(this);
}
handleChange(e) {
this.props.onTemperatureChange(e.target.value);//问题的关键
}
render() {
const temperature = this.props.temperature;
const scale = this.props.scale;
return (
<fieldset>
<legend>Enter temperature in {scaleNames[scale]}:</legend>
<input value={temperature}
onChange={this.handleChange} />
</fieldset>
);
}
}
class Calculator extends React.Component {
constructor(props) {
super(props);
this.handleCelsiusChange = this.handleCelsiusChange.bind(this);
this.handleFahrenheitChange = this.handleFahrenheitChange.bind(this);
this.state = {temperature: '',scale: 'c'};
}
//重点部分
handleCelsiusChange(temperature) {
this.setState({scale: 'c',temperature});
}
handleFahrenheitChange(temperature) {
this.setState({scale: 'f',temperature});
}
render() {
const scale = this.state.scale;
const temperature = this.state.temperature;
const celsius = scale === 'f' ? tryConvert(temperature,toCelsius) : temperature;
const fahrenheit = scale === 'c' ? tryConvert(temperature,toFahrenheit) : temperature;
return (
<div>
<TemperatureInput
scale="c"
temperature={celsius}
onTemperatureChange={this.handleCelsiusChange} />
<TemperatureInput
scale="f"
temperature={fahrenheit}
onTemperatureChange={this.handleFahrenheitChange} />
<BoilingVerdict
celsius={parseFloat(celsius)} />
</div>
);
}
}
这其中 <TemperatureInput
scale="c"
temperature={celsius}
onTemperatureChange={this.handleCelsiusChange} />
我们再看 这里需要强调一点的就是,每一个组件的状态都不受外界的影响,只能自己控制自己,外界是无法控制,就像是私有属性,只能类内部的函数才能改变,外界是无法直接改变的。 只有当自身组件的 这里简单说一下,上述实现同步代码的
这种从上而下的设计方式非常有助于我们调试程序,通过
(编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |