الفرق بين المراجعتين ل"React/lifting state up"

من موسوعة حسوب
اذهب إلى التنقل اذهب إلى البحث
سطر 12: سطر 12:
 
}
 
}
  
</syntaxhighlight>سنُنشِئ الآن مُكوِّن الآلة الحاسبة <code>Calculator</code>، والذي يُصيِّر حقل إدخال <code>[[HTML/input|<input>]]</code> يُتيح لنا إدخال درجة الحرارة ويحتفظ بقيمتها في <code>this.state.temperature</code>. يُصيِّر هذا المُكوِّن أيضًا المُكوِّن <code>BoilingVerdict</code> مع تزويده بدرجة الحرارة التي أدخلها المستخدم:
+
</syntaxhighlight>سنُنشِئ الآن مُكوِّن الآلة الحاسبة <code>Calculator</code>، والذي يُصيِّر حقل إدخال <code>[[HTML/input|<input>]]</code> يُتيح لنا إدخال درجة الحرارة ويحتفظ بقيمتها في <code>this.state.temperature</code>. يُصيِّر هذا المُكوِّن أيضًا المُكوِّن <code>BoilingVerdict</code> مع تزويده بدرجة الحرارة التي أدخلها المستخدم:<syntaxhighlight lang="javascript">
 +
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>أدخل درجة الحرارة بالسيلزيوس:</legend>
 +
        <input
 +
          value={temperature}
 +
          onChange={this.handleChange} />
 +
 
 +
        <BoilingVerdict
 +
          celsius={parseFloat(temperature)} />
 +
 
 +
      </fieldset>
 +
    );
 +
  }
 +
}
 +
 
 +
</syntaxhighlight>[https://codepen.io/gaearon/pen/ZXeOBm?editors=0010 جرّب المثال على موقع CodePen].
 +
 
 +
== إضافة حقل إدخال آخر ==
 +
المتطلّب الآخر الذي نريده إلى جانب إدخال الحرارة بالسيلزيوس هو تزويد المستخدم بحقل إدخال لدرجة الحرارة بالفهرنهايت وإبقائهما متزامنين معًا. بإمكاننا البدء باستخراج المُكوِّن <code>TemperatureInput</code> من المُكوِّن <code>Calculator</code>. سنضيف خاصيّة جديدة وهي المقياس <code>scale</code> والتي يُمكِن أن تكون قيمتها <code>"c"</code> أو <code>"f"</code>:<syntaxhighlight lang="javascript">
 +
const scaleNames = {
 +
  c: 'سيلزيوس',
 +
  f: 'فهرنهايت'
 +
};
 +
 
 +
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>
 +
    );
 +
  }
 +
}
 +
 
 +
</syntaxhighlight>نستطيع الآن تغيير المُكوِّن <code>Calculator</code> لتصيير حقلين منفصلين لإدخال درجة الحرارة:<syntaxhighlight lang="javascript">
 +
class Calculator extends React.Component {
 +
  render() {
 +
    return (
 +
      <div>
 +
        <TemperatureInput scale="c" />
 +
        <TemperatureInput scale="f" />
 +
      </div>
 +
    );
 +
  }
 +
}
 +
 
 +
</syntaxhighlight>[https://codepen.io/gaearon/pen/jGBryx?editors=0010 جرّب المثال على موقع CodePen].

مراجعة 09:36، 21 يوليو 2018

عادةً ما تحتاج المُكوِّنات المُتعدِّدة إلى أن تعكس نفس البيانات المتغيّرة. نُوصي برفع الحالة المشتركة بينها إلى أقرب عنصر أب مشترك بينها، فلنشاهد كيف يُمكِن تطبيق ذلك عمليًّا.

في هذا القسم سنُنشِئ آلة حاسبة للحرارة والتي تحسب إن كان الماء سيغلي في الدرجة المُعطاة.

سنبدأ بمُكوِّن يُدعى BoilingVerdict، والذي يقبل درجة الحرارة بالسيلزيوس celsius كخاصيّة props له، ويطبع إن كانت هذه الدرجة كافية لغلي الماء:

function BoilingVerdict(props) {
  if (props.celsius >= 100) {
    return <p>سيغلي الماء.</p>;
  }
  return <p>لن يغلي الماء.</p>;
}

سنُنشِئ الآن مُكوِّن الآلة الحاسبة Calculator، والذي يُصيِّر حقل إدخال <input> يُتيح لنا إدخال درجة الحرارة ويحتفظ بقيمتها في this.state.temperature. يُصيِّر هذا المُكوِّن أيضًا المُكوِّن BoilingVerdict مع تزويده بدرجة الحرارة التي أدخلها المستخدم:

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>أدخل درجة الحرارة بالسيلزيوس:</legend>
        <input
          value={temperature}
          onChange={this.handleChange} />

        <BoilingVerdict
          celsius={parseFloat(temperature)} />

      </fieldset>
    );
  }
}

جرّب المثال على موقع CodePen.

إضافة حقل إدخال آخر

المتطلّب الآخر الذي نريده إلى جانب إدخال الحرارة بالسيلزيوس هو تزويد المستخدم بحقل إدخال لدرجة الحرارة بالفهرنهايت وإبقائهما متزامنين معًا. بإمكاننا البدء باستخراج المُكوِّن TemperatureInput من المُكوِّن Calculator. سنضيف خاصيّة جديدة وهي المقياس scale والتي يُمكِن أن تكون قيمتها "c" أو "f":

const scaleNames = {
  c: 'سيلزيوس',
  f: 'فهرنهايت'
};

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>
    );
  }
}

نستطيع الآن تغيير المُكوِّن Calculator لتصيير حقلين منفصلين لإدخال درجة الحرارة:

class Calculator extends React.Component {
  render() {
    return (
      <div>
        <TemperatureInput scale="c" />
        <TemperatureInput scale="f" />
      </div>
    );
  }
}

جرّب المثال على موقع CodePen.