Flutter: القطعة السنانير

تم إنشاؤها على ١٢ ديسمبر ٢٠١٨  ·  100تعليقات  ·  مصدر: flutter/flutter

أعلن فريق React مؤخرًا عن خطافات: https://medium.com/@dan_abramov/making -sense-of-reaction-hooks-fdbde8803889. نظرًا لمدى تشابه Flutter مع React ، قد يكون من المثير للاهتمام معرفة ما إذا كانت هذه تتناسب مع Flutter أيضًا.

التعريف:

تتشابه الخطافات كثيرًا مع الخطاف State StatefulWidget مع اختلاف رئيسي واحد: يمكننا الحصول على العديد من الخطافات كما نحب على الأداة.
يمكن للخطافات الوصول إلى جميع دورات الحياة التي يمتلكها State (أو نسخة معدلة).

يمكن استخدام الخطافات على أي عنصر واجهة مستخدم محدد. على عكس State الذي يمكن استخدامه فقط لنوع عنصر واجهة مستخدم واحد محدد.

تختلف الخطافات عن المزيجات الفائقة لأنها لا يمكن أن تولد تعارضات. تعتبر الخطافات مستقلة _ بالكامل _ وليست مرتبطة بالقطعة.
هذا يعني أنه يمكن استخدام الخطاف لتخزين القيم وفضحها علانية دون خوف من التعارضات. هذا يعني أيضًا أنه يمكننا إعادة استخدام نفس الخطاف عدة مرات ، على عكس المزيجات.

المبدأ:

يتم تخزين الخطافات بشكل أساسي في Element في المصفوفة. لا يمكن الوصول إليها إلا من داخل طريقة build للأداة. ويجب الوصول إلى الخطافات دون قيد أو شرط ، على سبيل المثال:

فعل:

Widget build(BuildContext context) {
  Hook.use(MyHook());
}

لا تفعل:

Widget build(BuildContext context) {
  if (condition) {
    Hook.use(MyHook());
  }
}

قد يبدو هذا التقييد مقيدًا للغاية ، لكن السبب في ذلك هو تخزين الخطافات بواسطة الفهرس الخاص بهم. ليس نوعها ولا اسمها.
هذا يسمح بإعادة استخدام نفس الخطاف بقدر ما هو مطلوب ، دون أي تصادم.

حالة الاستخدام

الجزء الأكثر فائدة من الخطافات هو أنها تسمح باستخراج منطق دورة الحياة إلى مكون قابل لإعادة الاستخدام.

إحدى المشكلات النموذجية في أدوات Flutter هي الكائنات التي يمكن التخلص منها مثل AnimationController .
عادةً ما تتطلب تجاوز كل من initState و dispose . ولكن في الوقت نفسه لا يمكن استخراجه في مزيج لأسباب تتعلق بقابلية الصيانة.

يؤدي هذا إلى أداة Snipper الشائعة: stanim

class Example extends StatefulWidget {
  <strong i="7">@override</strong>
  ExampleState createState() => ExampleState();
}

class ExampleState extends State<Example>
    with SingleTickerProviderStateMixin {
  AnimationController _controller;

  <strong i="8">@override</strong>
  void initState() {
    super.initState();
    _controller = AnimationController(vsync: this, duration: const Duration(seconds: 1));
  }

  <strong i="9">@override</strong>
  void dispose() {
    super.dispose();
    _controller.dispose();
  }

  <strong i="10">@override</strong>
  Widget build(BuildContext context) {
    return Container(

    );
  }
}

تعمل الخطافات على حل هذه المشكلة عن طريق استخراج منطق دورة الحياة. هذا يؤدي إلى رمز أصغر بكثير:

class Example extends StatelessWidget {
  <strong i="15">@override</strong>
  Widget build(BuildContext context) {
    AnimationController controller = useAnimationController(duration: const Duration(seconds: 1));
    return Container(

    );
  }
}

يمكن أن يكون التنفيذ الساذج لمثل هذا الخطاف هو الوظيفة التالية:

AnimationController useAnimationController({Duration duration}) {
  // use another hook to obtain a TickerProvider
  final tickerProvider = useTickerProvider();

  // create an AnimationController once
  final animationController = useMemoized<AnimationController>(
    () => AnimationController(vsync: tickerProvider, duration: duration)
  );
  // register `dispose` method to be closed on widget removal
  useEffect(() => animationController.dispose, [animationController]), 

   // synchronize the arguments
  useValueChanged(duration, (_, __) {
    animationController.duration = duration;
  });

  return animationController;
}

useAnimationController هو واحد من هؤلاء "الخطاف".

حيث يكون التنفيذ الساذج لمثل هذا الخطاف كالتالي:

يجب أن يبدو هذا الرمز مشابهًا لشخص مستخدم في فئة State . لكن هذا يحتوي على بعض النقاط المثيرة للاهتمام:

  • يعتني الخطاف بالكامل بـ AnimationController ، من الإنشاء إلى التخلص. ولكن أيضًا التحديثات.
  • يمكن استخراجه بسهولة في عبوة قابلة لإعادة الاستخدام
  • كما أنه يعتني بتحديث duration عند إعادة التحميل السريع بدلاً من إنشاء AnimationController في initState .
  • يمكن للخطافات استخدام خطافات أخرى لبناء منطق أكثر تعقيدًا

عيوب

الخطافات لها تكلفة. الوصول إلى قيمة له عبء مشابه لـ InheritedElement . ويتطلبون أيضًا إنشاء مجموعة جديدة من الكائنات قصيرة العمر مثل الإغلاق أو "عنصر واجهة المستخدم".

لا يزال يتعين علي إجراء اختبار معياري لأرى الفرق الحقيقي بالرغم من ذلك


هناك مشكلة أخرى تتعلق بإعادة التحميل السريع.

إضافة خطافات في نهاية القائمة إذا كان جيدًا. ولكن نظرًا لأن الخطافات تعمل بناءً على ترتيبها ، فإن إضافة خطافات في منتصف الخطافات الموجودة سيؤدي إلى إعادة تعيين الحالة جزئيًا. مثال:

سيؤدي الانتقال من A, B إلى A, C, B إلى إعادة تعيين الحالة B (استدعاء كل من dispose و initHook مرة أخرى).

استنتاج

تعمل الخطافات على تبسيط _ الكثير_ من عالم الأدوات من خلال السماح بإعادة استخدام رمز أكبر. خاصة في السيناريوهات الشائعة جدًا مثل التخلص من القيمة وحفظها وحفظها.

يمكن استخدامها لاستبدال StatefulWidget بالكامل.

لكنهم يحتاجون إلى تحول ذهني ، وقد تكون إعادة ضبط الحالة الجزئية على إعادة البناء أمرًا مزعجًا.

من الممكن استخراج الخطافات خارج Flutter عن طريق إنشاء عناصر مخصصة. ليست هناك حاجة لتعديل المصادر حتى الآن.

ولكن نظرًا لخصوصية الخطافات ، فقد تستفيد _ الكثير _ من الوبر المخصص. الحزم الخارجية التي لا يمكن توفيرها في الوقت الحالي.

علاوة

~ يتوفر تطبيق قيد التنفيذ هنا: https://github.com/rrousselGit/flutter_hooks (أحدث الميزات موجودة في فرع prod-ready ). ~

~ تم التخطيط لإصدار قريبا على شكل ألفا. لكن التنفيذ الحالي يعمل إلى حد ما

متاح هنا https://pub.dartlang.org/packages/flutter_hooks# -readme-tab-

framework new feature

التعليق الأكثر فائدة

أردت فقط أن أقول - إذا كان أي شخص في فريق Flutter يرغب في الدردشة 1: 1 حول الخطافات ، فسأكون سعيدًا لشرح السياق التاريخي والتقني وراء سبب اعتمادنا لهم في React. قد يكون هذا التعليق ممتعًا أيضًا: https://github.com/reactjs/rfcs/pull/68#issuecomment -439314884.

ال 100 كومينتر

تضمين التغريدة

إليك متابعة لـ https://twitter.com/ericmander/status/1070024779015479302 مع بعض التفاصيل عما يدور في خلدي. فقط في حالة رغبة فريق Flutter في زيادة الاستثمار في هذا الموضوع

مرحبًا rousselGit ، كنت أنظر إلى حزمة flutter_hooks الخاصة بك في ذلك اليوم. لست متأكدًا من الخيارات المتوفرة لدينا لتنفيذها في Flutter ، لكنني لاحظت أنك تمرر طرق الخطاف من خلال HookContext ، بينما في React ، يمكن إنشاء الخطافات بشكل منفصل واستخدامها كنوع من "حالة mixin". الاختلاف الرئيسي هو أنه يبدو أن flutter_hooks يتطلب أن تكون جميع طرق الخطاف مضمنة في الحزمة ، بينما تسمح React بأن تكون طرق الخطاف منفصلة تمامًا.

يبدو أن هذا سيكون مهمًا لمطابقة مواصفات React. هل لديك أي أفكار حول كيفية تحقيق ذلك؟

تحرير :

تمت إزالة HookContext وأصبحت جميع الخطافات الآن طرقًا ثابتة. لذا فإن ما يلي قد عفا عليه الزمن الآن


تقوم الحزمة الخاصة بي بذلك لغرض الإكمال التلقائي ، ولكنها ليست ضرورة.

بدلا من

context.useSomeHook()

فإننا يمكن أن يكون

useSomeHook(context)

هذا لا يغير شيئًا سوى قابلية الاكتشاف.

السمة الرئيسية هي

T HookContext.use<T>(Hook);

مما يسمح لك ببناء خطافاتك الخاصة من هناك. طالما لدينا هذه الطريقة ، يمكننا فعل كل شيء تفعله React.

ولكن نظرًا لخصوصية الخطافات ، فإنها ستستفيد كثيرًا من الوبر المخصص. الحزم الخارجية التي لا يمكن توفيرها في الوقت الحالي.

أوصيك بالتصويت (وإضافة حالة الاستخدام الخاصة بك إلى)
https://github.com/dart-lang/linter/issues/697. سيكون أمرًا رائعًا أن توفر الحزم أكياسًا مخصصة خاصة بها.

هناك مشكلة أخرى تتعلق بإعادة التحميل السريع.

هذا واحد يقلقني سيكون من المحزن أن نحط من تجربة إعادة التحميل الساخنة.

متاح هنا https://pub.dartlang.org/packages/flutter_hooks

هل يمكنك توضيح مزايا خبز هذا في إطار Flutter على مجرد وجود حزمة خارجية؟

حول إعادة التحميل الساخن ، قمت بدمجه وهو سهل الاستخدام.

المشكلة الحقيقية الوحيدة هي # 26503 ، والتي يبدو أنها تتطلب تغيير الأدوات لإصلاحها. وليس لدي النطاق الترددي للقيام بذلك.


هناك العديد من التحسينات الصغيرة التي يمكننا إدخالها على الخطافات من خلال دمجها في Flutter:

  • زيادة بعض الأداء ، من خلال عدم الاعتماد على StatefulElement
  • إعادة البناء / التحليل ، وهو أمر غير ممكن حاليًا أو محدود للغاية باستخدام analzer_plugin

لكني أعتقد أن السبب الأكبر هو: الخطافات هي جزء من عمل على نطاق أوسع في React ، وهذا هو العرض غير المتزامن.

إذا أراد Flutter يومًا ما أن يسير في طريق Async Rendering (ويجب أن يكون كذلك) ، فسيتطلب الأمر شيئين:

  • تغييرات متعددة في إطار العمل
  • شيء مشابه للخطافات

هناك أيضًا الجانب المجتمعي الواضح. مع 270 نجمة في شهر وموقع على https://github.com/trending/dart ؟

الهدف من الخطافات هو تغيير بنية عناصر واجهة المستخدم بحيث يمكن للأشخاص مشاركة منطق دورة الحياة المحدد للنشر.

مع دعم الخطافات رسميًا ، سيؤدي ذلك إلى زيادة جهود المجتمع بشكل كبير.

فضولي: هل يمكن أن تشرح كيف جعلته يعمل من أجل إعادة التحميل السريع؟

قمت بتوسيع StatefulElement بدلاً من ComponentElement ، حتى أتمكن من الوصول إلى reassemble .
يتيح هذا للمكالمة التالية build تغيير قائمة الخطاف مع منع إعادة البناء العادية من القيام بذلك.

بشكل أساسي ، إذا كان previousHook.runtimeType != newHook.runtimeType في مؤشر معين ، فسيتم التخلص من هذا الخطاف وكل ما يلي.

يرجع الجزء "كل ما يلي" إلى أنه يمكن للخطاف استخدام خطافات أخرى ؛ لذا فمجرد إزالة واحد لا يكفي.
منذ شهر من الاستخدام المتواصل ، نادرًا ما تكون هذه مشكلة.

إنه في الواقع عكس ذلك ، يبدو أن تجربة إعادة التحميل السريع محسّنة. نظرًا لأن كل شيء يقع ضمن طريقة build ، فإن إعادة التحميل السريع تطبق التغييرات دائمًا (على عكس initState ). مثال نموذجي هو AnimationController :

final animationController = useAnimationController(duration: const Duration(second: 1));

يسمح هذا الخطاف بإعادة التحميل السلس للمدة ؛ وهو شيء يتطلب عادةً إعادة التشغيل السريع.

بدأت في ترجمة جزء من تطبيقي الرئيسي لإزالة بعض النصوص المعيارية. لا أرى الخطافات كميزة بل نمط كامل. هناك العديد من الموضوعات التي تنتظر تنفيذها وستعود بالفائدة على الإنتاجية وكذلك الصيانة. لقد بدأت مع الرسوم المتحركة ، وإزالة وحدات التحكم ، وأود أن أرى Hooks for Firebase أو الحالات الشائعة الأخرى.

إنه في الواقع عكس ذلك ، يبدو أن تجربة إعادة التحميل السريع محسّنة. نظرًا لأن كل شيء ضمن طريقة الإنشاء ، فإن إعادة التحميل الفوري تطبق التغييرات دائمًا (على عكس الحالة المبدئية).

👍 لقد وصلت إلى هذا الإدراك أيضًا بعد أسابيع قليلة من رؤيتي لأول مرة عرض سيباستيان.

يرجع الجزء "كل ما يلي" إلى أنه يمكن للخطاف استخدام خطافات أخرى ؛ لذا فمجرد إزالة واحد لا يكفي.

اعتقدت أيضًا أنه في JS ربما يكون الاستدلال مفيدًا: إذا تسببت إعادة التحميل الساخنة في طرح render (Flutter's build ) (على سبيل المثال بسبب الأنواع غير المتطابقة) ، نقوم بإعادة تعيين حالة الخطافات وإعادة المحاولة. إذا فشلت مرة أخرى فإننا نفشل.

أعتقد أنه ليس لديك هذه المشكلة بسبب الكتابة القوية؟ لست متأكد. ماذا يحدث إذا بدأت التحرير باستخدام حالة سلسلة Hook ثم غيرت الكود على افتراض أنه رقم؟

ماذا يحدث إذا بدأت التحرير باستخدام حالة سلسلة Hook ثم غيرت الكود على افتراض أنه رقم؟

تقصد الذهاب من:

final counter = useState(0)

ل:

final name = useState('foo');

؟

إذا كان الأمر كذلك ، فإن نظام الكتابة يكتشف بشكل صحيح أن النوع قد تغير. هذا لأن نوع useState هو في الواقع useState<int> مقابل useState<String> .

من المحتمل أن يمر JS بوقت أصعب هنا.

أنا لا أفهم حقًا ما الذي يوفره لك هذا. إعلان واحد سهل الفهم ، وسطر واحد سهل الفهم في initState ، وسطر واحد سهل الفهم في التخلص ، يتم استبدالها بخط أقل كفاءة وغير شفاف تمامًا في طريقة البناء (حيث يكون الأداء حرج). هذا لا يبدو صفقة جيدة. هل يمكنك توضيح الفوائد هنا؟

(ومع ذلك ، يبدو أن https://pub.dartlang.org/packages/flutter_hooks يبدو أنه ينفذ كل شيء هنا بالفعل ، لذلك أعتقد أننا لسنا بحاجة إلى إضافة أي شيء إلى النظام الأساسي؟)

الخطافات هي أحد الحلول لمشكلة واجهتها React لسنوات. وبما أن Flutter يأخذ الكثير من الإلهام من React ، فقد استورد هذه المشكلات أيضًا.

أنا سيء جدًا في التسويق ، لذلك أقترح بشدة مشاهدة حديث فريق React عن هذه الأمور. تبدأ المقدمة هنا https://youtu.be/dpw9EHDh2bM.

تليها مقارنة جنبًا إلى جنب مع ما قبل / بعد من دان أبراموف (الذي أجاب هنا على بعض التعليقات أعلاه).

النقطة المهمة هي أن كل شيء يبقون فيه في هذا الحديث ينطبق على Flutter أيضًا (بما في ذلك مدونتهم حول الخلطات الضارة https://reactjs.org/blog/2016/07/13/mixins-consoded-harmful.html)


ومع ذلك ، يمكن تلخيص الخطافات في الجملة الجذابة التالية:

باستخدام الخطافات ، يمكنك "الحصول على" نسبة أكبر من تطبيقك

هذا لأنه يمكن استخراج الخطافات بالكامل من الأداة ونشرها للنشر ليستخدمها الآخرون. هذا شيء مستحيل حاليًا مع StatefulWidget لأن منطقنا مرتبط بدورات الحياة State .

تأثير آخر للخطافات هو أنه يغير كيفية تجميع الكود. لدينا حاليًا ما يلي:

initState() {
  a = A(widget.foo);
  b = B(widget.bar);
}

didUpdateWidget(SomeWidget old) {
  if (old.foo != widget.foo) {
    a.foo = widget.foo;
  }
  if (old.bar != widget.bar) {
    b.bar = widget.bar;
  }
}

dispose() {
  a.dispose();
  b.dispose();
}

يتم خلط كل شيء وتقسيمه عبر دورات حياة متعددة. يصبح من الصعب جدًا معرفة ما إذا كنا قد نسينا التخلص من متغير / تحديثه.

مع الخطافات يصبح ما يلي:

final a = useMemoized(() => A(foo));
useValueChanged(foo, () => a.foo = foo});
useEffect(() => a.dispose, [a]);

final b = useMemoized(() => B(bar));
useValueChanged(bar, () => b.bar = bar});
useEffect(() => b.dispose, [b]);

تم إعادة تجميع كل شيء الآن. يصبح الأمر أكثر وضوحًا إذا نسينا التخلص من متغير / تحديثه أم لا ، ويمكننا بسهولة استخراج هذا المنطق في وظيفة ثابتة تقوم بكل شيء داخليًا.

الخطافات متوافقة مع جاف. نكتب مرة واحدة المنطق لإنشاء / تحديث / التخلص من متغير. ونعيد استخدامه في كل مكان بدلاً من نسخه ولصقه.

مثال مرئي (في React):


بشكل عام ، في حين أنه من غير المعقول أنه من الممكن تنفيذ الخطافات خارج مستودع Flutter ؛ لا أعتقد أنه يجب أن يبقى كما هو.

يبدو الأمر كما لو أن Flutter قدم فقط الفئة الأساسية Widget ، وحقق StatefulWidget كاعتماد خارجي: لا معنى له.

Flutter هو إطار عمل ، لا نريد تقديم الأساسيات فقط

مما يعني أننا نريد أيضًا:

  • توفير خطافات لجميع جوانب الهيكل التي يمكن أن تستفيد منها
  • التفاعل مع فاحص الأدوات (لم يتم تحسين واجهة المستخدم الحالية لحالة الاستخدام هذه)
  • إعادة بيع ديون / لينتر
  • توفير فائدة الاختبار

يتطلب ذلك قدرًا كبيرًا من العمل وقد يتطلب العديد من العلاقات العامة في Flutter.
إنه بعيد جدًا عن نطاق الحزمة الصغيرة التي يحتفظ بها رجل واحد في وقت فراغه.

الخطافات جافة وهي مزيج من منطق الأعمال / الحالة التي تعزز الموقع النظيف للرمز. البديل هو التكرار المجزأ عبر قاعدة بيانات.

بينما أوافق على أنه على الورق يكون أكثر غموضًا ، فإن النمط قابل للتكرار ومفهوم ، لذلك بعد يوم من الاستخدام يصبح شفافًا. إنه مثل أي نمط برمجة آخر: معتم عند البدء ، وشفاف عند استخدامه ، ولكن مع الخطافات يكون الانتقال فوريًا تقريبًا.

في رد الفعل ، يعتقد العديد من المطورين أن الخطافات تجعل العديد من الحالات التي تعتمد في الأصل على مكونات الفصل ليست ضرورية. لذلك ، سيأتي المكون الوظيفي في مركز المسرح في المستقبل القريب.

سؤالي الساذج هو ما إذا كان دعم عنصر واجهة مستخدم وظيفي في الرفرفة أمرًا منطقيًا أيضًا. أتفهم أن الأداة الوظيفية حاليًا غير موصى بها بسبب عدم الارتباط بالعنصر الخاص بها وعدم وجود BuildContext الخاص بها. هل سيكون من المفيد تقديم آلية وظيفية جديدة يمكنها إنشاء نفس الكائنات الموجودة أسفل عناصر واجهة المستخدم؟

ivenxu هذا شيء أنشأته أيضًا ، في حزمة أخرى: https://github.com/rrousselGit/functional_widget

إنه منشئ رمز يقوم بإنشاء فئة من وظيفة (مع مفاتيح وكل شيء) ومتوافق مع الخطافات لتوليد HookWidget

مجموع كلاهما:

<strong i="11">@hwidget</strong>
Widget foo(BuildContext context, {Duration duration}) {
  final controller = useAninationController(duration: duration);
  useEffect(controller.forward, [controller]);

  final value = useAnination(controller);
  return Text(value.toString());
}

إنه يجعل نصًا لطيفًا ينتقل من 0 إلى 1 بشكل تدريجي.
في 6 أسطر من التعليمات البرمجية ...
الأمر الذي قد يتطلب أكثر من 30 سطرًا مع عناصر واجهة المستخدم المعتادة.

وأنا لا أحسب عمليات التخطي التي تم إنشاؤها تلقائيًا debugFillProperties و operator== .

rousselGit كنت على دراية بعملك الخاص بالقطعة الوظيفية والأشياء الجيدة والشكر! ومع ذلك ، أنا أتحدث عن الدعم المحلي من الرفرفة.

بالمناسبة ، كيف ينتقل التصحيح المرفق إلى الشفرة العامة؟ هل هذا ممكن وضع نقطة فاصل في foo () وفحص المتغير المحلي؟ كيف تبدو Callstack؟

في بعض الأحيان ، يكون النموذج الوظيفي للمكون / عنصر واجهة المستخدم أكثر إيجازًا من نظيره في الفئة. لذلك أنا أبحث عن أفكار حول ما إذا كانت الأداة الوظيفية المدعومة محليًا ستحدث أي فرق.

مع الخطافات يصبح ما يلي

أعتقد حقًا أن الصورة "قبل" هنا أكثر وضوحًا وأسهل في الفهم من الصورة "اللاحقة". من الواضح ، مع ذلك ، أن هذا رأي شخصي.

يبدو الأمر كما لو أن Flutter قدم فقط فئة Widget الأساسية ، وجعل StatefulWidget بمثابة تبعية خارجية: لا معنى له.

إن القيام بذلك سيكون في الواقع متماشياً إلى حد كبير مع فلسفة طبقات Flutter. السبب الرئيسي لوجود StatefulWidget كجزء أساسي من الطبقة الأولى من طبقة عناصر واجهة المستخدم في إطار العمل هو أن الميزات الأخرى في إطار العمل تعتمد عليها (على سبيل المثال GlobalKey ) ، لذلك لا يمكننا ذلك. ولكن بقدر الإمكان ، نحب استخراج الميزات بحيث لا تكون في جوهرها.

أعتقد أنه من المنطقي أن يكون لديك هذا كحزمة لأولئك الأشخاص الذين يرغبون في استخدامه. إذا كان هناك أي شيء يمكننا القيام به في إطار العمل الأساسي لجعل تنفيذه أفضل وأكثر كفاءة ، وما إلى ذلك ، فعلينا بالتأكيد القيام بذلك.

أعتقد أن هذا مشروع رائع ، وأنا أتابع الحزمة باهتمام.

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

rousselGit أظن أنك ستحقق الكثير من النجاح في الاستمرار في تطوير هذا كحزمة منفصلة وقضايا افتتاحية / علاقات عامة لإطار العمل الأساسي الذي من شأنه أن يساعد في إنجاحه أكثر. إذا كان هناك شيء تحتاج إلى كشفه في إطار العمل ليس حاليًا لإنجاح هذا الأمر ، فلنتحدث عنه. إذا كان هناك خطأ في إطار العمل يمنع هذا من العمل ، فلنجعله يعمل!

و FWIW ، أقول إن هذا كان لديه تجربة مماثلة مع flutter_svg - مما أدى إلى بعض المساهمات في إطار العمل وكان قادرًا على أن يكون مفيدًا للعديد من الأشخاص كحزمة واحدة.

لقد أدركت للتو:
إذا تم تنفيذ الخطافات في Flutter ، فإن المرشح الجيد هو ComponentElement.

هذا يعني أنه بدلاً من وجود نوع عنصر واجهة مستخدم جديد ، فإنه سيجعل كلاً من StatelessWidget و StatefulWidget متوافقين مع الخطافات.

هذا النهج يمكن أن يسمح لكلا بناء الجملة للتعايش. قد يكون هذا مفيدًا بالنظر إلى أن لكل من بناء الجملة إيجابيات وسلبيات


أنا بخير مع وجود الخطافات خارج Flutter في الوقت الحالي.

قلقي الوحيد هو أنه من خلال كونه غير رسمي ، سيؤدي ذلك إلى تقليل الاستخدام العام للخطافات. وبالتالي تقليل عدد الخطافات المتوفرة في الحانة.

بالنظر إلى أكبر ميزة للخطافات هو تأثير المجتمع (يمكن نشر الخطافات المخصصة في الحانة) ، فهذا يضر بفائدتها.

أردت فقط أن أقول - إذا كان أي شخص في فريق Flutter يرغب في الدردشة 1: 1 حول الخطافات ، فسأكون سعيدًا لشرح السياق التاريخي والتقني وراء سبب اعتمادنا لهم في React. قد يكون هذا التعليق ممتعًا أيضًا: https://github.com/reactjs/rfcs/pull/68#issuecomment -439314884.

Hixie أو dnfield هل تواصل أحد منكم معgaearon؟

بصفتي مستخدم Flutter الذي يستخدم أيضًا React كثيرًا ، يمكنني القول أن الخطافات كانت بمثابة تغيير حقيقي لقواعد اللعبة بالنسبة إلى React. أنا أكتب كل شفراتي الجديدة باستخدام الخطافات حصريًا ، وأقوم بنقل أي فئات قديمة إلى خطافات أثناء عملي عليها. فوائد وجود كل التعليمات البرمجية المتعلقة بجزء معين من المكون الخاص بك في نفس المكان مذهلة!

أعتقد أنه سيكون من الرائع بذل جهد لتقييم ما إذا كان هذا النموذج يتناسب مع Flutter أم لا

لقد فاتني هذا التعليق! لقد تواصلت معهم للتو.

يجب أن أعترف أنني لا أفهم حقًا كيف ينطبق الخطاف على Flutter. توجد بعض حزم الخطافات بالفعل إذا كنت تريد تجربتها (بعضها مذكور في هذا الخطأ أعلاه). في الأساس ، أنا لا أفهم حقًا المشكلة التي يحلها المفهوم.

لمزيد من التفاصيل حول وجهة نظري هنا ، انظر تعليقاتي السابقة: https://github.com/flutter/flutter/issues/25280#issuecomment -455846788 ، https://github.com/flutter/flutter/issues/25280#issuecomment - 455847134 ، https://github.com/flutter/flutter/issues/25280#issuecomment -456272076.

في الأساس ، أنا لا أفهم حقًا المشكلة التي يحلها المفهوم.

الخطافات هي مثل مزيج الحالة ، ولكن بدون المشكلات الكامنة في الخلطات: لا يوجد تعارض متغير ، ويمكن استخدامها أكثر من مرة.

يمكن أن تحل الخطافات واحدة من أكبر المشكلات التي تواجه Flutter مع Widgets ذات الحالة في الوقت الحالي: التعامل مع كل وحدات التحكم هذه.

تحتاج كل وحدة تحكم إلى كل من initState و didUpdateWidget والتخلص منها ، والتي يتم تنفيذها بنفس الطريقة دائمًا.

لا يمكننا استخراجه إلى فئة أساسية / mixin لأننا قد نحتاج إلى أكثر من فئة.
لذا بدلاً من ذلك علينا نسخ ولصق المنطق في كل مكان.
لكن هذا ليس جيدًا أيضًا. من السهل أن تنسى خطوة ، مثل تجاوز dispose .


المشكلة الحقيقية في الخطافات هي أنها تتطلب الكثير من العمل لتنفيذها.

الإطار الأساسي بسيط. ولكن نظرًا لسلوكهم الفريد ، فإنهم يحتاجون إلى تكامل عميق مع أدوات إعادة البناء والتلتر.

وللتنفيذ الأمثل ، قد تكون هناك حاجة لبعض ميزات اللغات مثل tupple / التدمير.

لا أشعر أن هذا يعالج حقًا التعليقات التي لدي أعلاه (https://github.com/flutter/flutter/issues/25280#issuecomment-455846788 و https://github.com/flutter/flutter/issues/25280# الإصدار 456272076 على وجه الخصوص).

Hum ، من المحتمل أن يشرح gaearon الأمر بشكل أفضل مني ، ولكن من وجهة نظري:

  • تعتمد حجة المقروئية على حجم الأداة. في الأدوات الكبيرة ، تميل الخطافات إلى أن تكون في الواقع _ أكثر _ قابلة للقراءة لأن كل البتات ذات الصلة تكون معًا بدلاً من أن تنتشر عبر دورات الحياة.

  • أقل البق. تجعل واجهة برمجة التطبيقات التعريفية الخاصة بهم من الصعب نسيان تحديث / تنظيف الحالة.

  • حول "لماذا يجب أن تكون جوهرية؟" ، أنا أحب المجاز الذي استخدمه دان أبراموف.
    الخطافات هي أدوات لماهية الإلكترونات للذرات.
    ليس من المنطقي استبعادهم ، عندما يكونون بدائيين مستخدمين لبناء أشياء أعظم.
    لا يتعلق الأمر فقط بتنفيذ الخطافات. يمكن أن يستفيد منها الإطار بأكمله.
    يمكن استخدامها لتحسين أشياء مثل الرسوم المتحركة والنماذج وغير ذلك الكثير.

Hixie ، هل قضيت وقتًا في استخدام الخطافات ، أم أنك تقوم بجدولة البيانات لاتخاذ قرار؟ لست متأكدًا من النسبة المئوية للوقت الذي يقضيه فريق Flutter في كتابة عناصر إطار العمل مقابل كتابة التطبيقات للعملاء. أظن أن الأشخاص الذين يكتبون تطبيقات للعملاء سوف يتعاملون مع هذا السؤال من زاوية مختلفة قليلاً عن تطوير إطار العمل. أي ، كيف يجعلني هذا أكثر فاعلية ويقدم قيمة أكبر لعملائي ، ليس إذا كان يفي بنفس معايير الحل الحالي.

لقد قدمت flutter_hooks مؤخرًا مع function_widget في أحد تطبيقاتنا الساخنة الجديدة.

لقد قلل إلى حد كبير الكود المعياري وبعد إعادة هيكلة كل تلك الأدوات المصغّرة ذات الحالة الفوضوية إلى وظائف صغيرة باستخدام الخطافات ، تقلص قاعدة الكود بنسبة 70٪ تقريبًا.

من وجهة نظر ذات مستوى أعلى ، فإن عنصر واجهة المستخدم الوظيفي الذي يحتوي على مجموعة من الخطافات يشبه التبسيط الضروري للجمع بين العديد من العناصر المرئية باستخدام combLatest في RX. ولكن بدلاً من النص صراحةً على كل ما يمكن ملاحظته في التمهيد ووجود وظيفة تعمل عليها ، فإن الخطافات هي طريقة أكثر مرونة لأنك تنسجها في الكود حيث تحتاج إلى القيمة.

ولكن ، في النهاية ، كل عنصر واجهة مستخدم مثل مرحلة في تدفق RX.

أنا بالتأكيد لا أعتقد أنه يجب علينا إزالة flutter_hooks. أنا فقط لا أرى ما يمكننا (فريق Flutter) تقديمه وهو أكثر قيمة.

الخطافات هي أدوات لماهية الإلكترونات للذرات.

أعتقد أننا إذا اتبعنا هذه الاستعارة فيجب أن تنظر إلى Flutter على أنها كواركات ، أو ربما الهادرونات. إلكترونات الخطافات هي طبقة فوقها.

Hixie ، هل قضيت وقتًا في استخدام الخطافات ، أم أنك تقوم بجدولة البيانات لاتخاذ قرار؟ لست متأكدًا من النسبة المئوية للوقت الذي يقضيه فريق Flutter في كتابة عناصر إطار العمل مقابل كتابة التطبيقات للعملاء.

أنا لم أستخدم الخطافات بنفسي. أنا أكتب تطبيقات مع Flutter. لم أجد أي حاجة لأي شيء مثل الخطافات عند القيام بذلك. كما هو مذكور أعلاه ، على الرغم من ذلك ، لا أعتقد أن الخطافات تتطابق مع أسلوب التطوير الخاص بي (أفضل رؤية النموذج المعياري). لا أرغب بالتأكيد في إزالة الخطافات من أي شخص يريد استخدامه.

أنا فقط لا أرى ما يمكننا (فريق Flutter) تقديمه وهو أكثر قيمة.

لجعل الخطافات مفيدة حقًا ، يحتاجون إلى مكون إضافي للمحلل وخيارات إعادة بناء مخصصة.
فقط مع هذه السنانير تتألق حقًا.

تسمح الخطافات بإجراء تحليل ثابت قوي للغاية وهو أمر مستحيل باستخدام StatefulWidget النموذجية.
هذا يجعل إدارة الحالة المحلية لعنصر واجهة مستخدم أكثر أمانًا / قابلية للتوسع. بالنسبة لي ، فإن الحد المعياري هو مجرد مكافأة.

ولكن:

  • هناك الكثير من العمل على واجهات برمجة التطبيقات منخفضة المستوى للغاية.
  • واجهة البرنامج المساعد للمحلل غير مستقرة ، ومفتقرة ، وغير مستخدمة تقريبًا ، وغير موصى بها من قبل الفريق (حيث يوجد تحليل واحد يتم إجراؤه لكل مكون إضافي)
  • لا يستخدم flutter نفسه واجهة برمجة تطبيقات البرنامج المساعد وبدلاً من ذلك قام بتطبيقه مباشرة على الخادم

لذلك ، كحزمة يحتفظ بها المجتمع ، فإن احتمال وجود أدوات كاملة للخطافات منخفض للغاية.

أعتقد أننا إذا اتبعنا هذه الاستعارة فيجب أن تنظر إلى Flutter على أنها كواركات ، أو ربما الهادرونات. إلكترونات الخطافات هي طبقة فوقها.

إذا كانت Flutter عبارة عن كواركات ، فهي أيضًا مجرة.

لدينا بالفعل فصول منخفضة المستوى مثل Layer .
ولكن هناك أيضًا قدرًا هائلاً من الفصول عالية المستوى مثل Switch .

يمكن استخراج مكتبات المواد وكوبرتينو بأكملها كحزم ، ثم Navigator ، وكائنات ذات صلة بالنموذج. لكنهم ليسوا كذلك.
والخطافات عبارة عن طبقات قليلة أسفل هذه.

غير ذي صلة ولكني أعتقد بشدة أن Material و Cupertino لا ينبغي أن يكونا في مكتبة Flutter الأساسية لأنها تعزز الافتقار إلى واجهات جيدة موضوعة في مكان ما بين المكونات ذات المستوى المنخفض للغاية والمواد عالية المستوى. إذا حاولت يومًا إنشاء تطبيق بدون مكتبة المواد ، فسيكون ذلك صعبًا للغاية.

لا تتعلق الخطافات بالفعل بتقليل الصيغة المعيارية. (نحن لا نمانع أيضًا في التعميم). القيمة الأساسية بالنسبة لي هي القدرة على تغليف وتكوين منطق مفصل.

const [value, setValue] = useState(0)
const debouncedValue = useDebounced(value, 1000)
const interpolatedValue = useSpring(debouncedValue, {
  friction: 10,
  mass: 20
})

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

لجعل الخطافات مفيدة حقًا ، يحتاجون إلى مكون إضافي للمحلل وخيارات إعادة بناء مخصصة.
فقط مع هذه السنانير تتألق حقًا.

أوافق على أننا بحاجة إلى دعم هذا. يجب أن يكون هذا خطأ تم رفعه ضد مشروع Dart GitHub. أود منا أن ننقل النسالات الخاصة بـ Flutter من قاعدة بيانات Dart ، بالتأكيد.

يمكن استخراج مكتبات المواد وكوبرتينو بأكملها كحزم ، ثم Navigator ، وكائنات ذات صلة بالنموذج. لكنهم ليسوا كذلك.

نعم ، ربما يكون هذا صحيحًا أيضًا. هناك أسباب عملية لعدم قيامنا بذلك (على سبيل المثال ، سيؤدي ذلك إلى تعقيد "Hello World" مما يجعل من الصعب البدء في استخدام Flutter) ، ولكن يمكننا التفكير في ذلك بالرغم من ذلك. مرة أخرى ، رغم ذلك ، فهذه مشكلة منفصلة يجب أن نقدمها بشكل منفصل إذا أردنا النظر فيها.

القيمة الأساسية بالنسبة لي هي القدرة على تغليف وتكوين المنطق ذي الحالة.

هذا هو حقا قيمة جدا. ليس من الواضح ما إذا كان يجب أن يكون في إطار العمل الأساسي.

هذا هو حقا قيمة جدا. ليس من الواضح ما إذا كان يجب أن يكون في إطار العمل الأساسي.

هذا من شأنه أن يسمح بإهمال بعض الخلطات الأساسية للدولة.

على سبيل المثال ، AutomaticKeepAliveClientMixin في وضع غريب.
علينا استدعاء super.build ، وهو أمر غير بديهي للغاية. ويعود هذا super.build null والذي لن يعمل مع الأنواع غير القابلة للإلغاء.
ولكن كخطاف ، تم حل هاتين المسألتين.

وبالمثل ، لن نحتاج إلى كل من SingleTickerProviderStateMixin و TickerProviderStateMixin نظرًا لأن الخطافات قابلة لإعادة الاستخدام عدة مرات حسب الرغبة.

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

لن نستخدم الخطافات في إطار العمل الأساسي ، نظرًا لأن IMHO تجعل الأشياء أقل قابلية للقراءة. لذا فإن وجودهم في إطار العمل الأساسي لن يساعد في إزالة التعليمات البرمجية الأخرى.

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

إذا كانت الخطافات جيدة ، فسيستخدمها الأشخاص بغض النظر عما إذا كانت من مشروع Flutter مفتوح المصدر أو ، على سبيل المثال ، مشروع Hooks مفتوح المصدر.

لن نستخدم الخطافات في إطار العمل الأساسي ، نظرًا لأن IMHO تجعل الأشياء أقل قابلية للقراءة. لذا فإن وجودهم في إطار العمل الأساسي لن يساعد في إزالة التعليمات البرمجية الأخرى.

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

إذا كانت الخطافات جيدة ، فسيستخدمها الأشخاص بغض النظر عما إذا كانت من مشروع Flutter مفتوح المصدر أو ، على سبيل المثال ، مشروع Hooks مفتوح المصدر.

هذه ليست فكرة سيئة يمكن تشغيل الخطافات كمشروع مفتوح المصدر منفصل. هل سيأخذ الفريق الأساسي الأولوية لمتطلبات التغيير الأساسي من مشروع Hook؟ IMHO من المهم جدًا لنجاح مشروع الخطاف.

ما هو "شرط التغيير الأساسي"؟

ما هو "شرط التغيير الأساسي"؟

Devtools.
بشكل أساسي حول المكونات الإضافية للمحلل ، ولكن من المحتمل أيضًا أن يكون نظامًا إضافيًا على أدوات الرفرفة / devtools.

هناك الكثير من العمل المتضمن هناك ، ولا يمكن للمجتمع المحلي القيام به.

لن نستخدم الخطافات في إطار العمل الأساسي ، نظرًا لأن IMHO تجعل الأشياء أقل قابلية للقراءة. لذا فإن وجودهم في إطار العمل الأساسي لن يساعد في إزالة التعليمات البرمجية الأخرى.

مع كل الاحترام ، لكن هذا يبدو جاهلاً بعض الشيء. يجب أن تجربهم حقًا! إنها طريقة أكثر إيجازًا من الرقص باستخدام initState / dispose / setState / build لكل جانب من جوانب الحالة.

يتمحور Flutter حول التكوين واستخدام الخطافات يتبع بشكل طبيعي نمط التكوين حيث يكون استخدام mixins من ناحية أخرى هو عكس التركيب.

أتخيل أننا سنستمر في النظر في جعل المحلل القابل للتوسعة أولوية عالية. لسوء الحظ ، هناك العديد من الأولويات العليا الأخرى ، مثل تحسين تجربة المهام الأساسية في الساعة الأولى وتنفيذ الأدوات للتغيير غير القابل للإلغاء افتراضيًا.

بعد قولي هذا ، لا أفهم سبب عدم تمكن غير موظفي Google من القيام بذلك. يعد كل من Flutter و Dart مشروعين مفتوحين المصدر ويتم تنفيذ العديد من الأشياء بواسطة غير موظفي Google.

بعد قولي هذا ، لا أفهم سبب عدم تمكن غير موظفي Google من القيام بذلك. يعد كل من Flutter و Dart مشروعين مفتوحين المصدر ويتم تنفيذ العديد من الأشياء بواسطة غير موظفي Google.

نحن نتحدث عن شهور من العمل في مشاريع متعددة ، لأشياء يعتبرها الفريق "ميزات ذات أولوية منخفضة" ، مع العديد من التغييرات الكبيرة. والمشروعات المتأثرة منخفضة للغاية مع عدم وجود وثائق عامة تقريبًا.

الاستثمار المطلوب ومخاطر الرفض / الوقوع في المنتصف مرتفعة للغاية. خاصة عندما لا نحصل على أي أموال منه.

لذا بينما أفهم وجهة نظرك ، فمن غير المحتمل للغاية

هل هناك أي خارطة طريق حول ذلك؟ هل لديك أي فكرة عما إذا كان من الممكن أن تهبط الخطافات في رفرفة ومتى؟

إذا نجح Flutter (وهو ما آمل أن يحدث) خلال عام واحد ، فإن كل مطور React يحاول الانضمام إلى Flutter سوف يصرخ عندما يكتشف أنه لا يوجد دعم من الدرجة الأولى للخطافات هنا.

اتخذ فريق Flutter قرارًا جيدًا بنسخ نموذج React المستند إلى الفصل ، ولكن هذا شيء من الماضي الآن ، والمكونات الوظيفية والخطافات هي المستقبل ، يجب على فريق Flutter أن يستيقظ على هذا الواقع الجديد إذا كانوا يريدون البقاء على قدم المساواة .

دقيق كما ذكر cgarciae ، ينتقل مجتمع React إلى الارتباط والمكون الوظيفي للمضي قدمًا. وهذا يجعل الرفرفة تبدو قديمة ، لأن نموذج البرمجة والإنتاجية لن يتساوى مع حلول تطوير الأنظمة الأساسية الأخرى.

بعد تجربة التفاعل والرفرفة مؤخرًا ، فإن فقد الخطاف في الرفرفة يترك فجوة كبيرة فيما يتعلق بالإنتاجية والاتساق وقابلية الصيانة للشقة قيد المقارنة. لن تساعد المنظمة في تبني الرفرفة في مشروع جديد ، أو إقناع الناس بالتبديل من حل قاعدة React إلى الرفرفة التي تستحق الجهد المبذول.

أتفهم تمامًا عندما يقوم شخص ما ببناء مجموعة أدوات ، قد لا يبدو تنفيذ إطار عمل منخفض المستوى ، رمز معياري مشكلة كبيرة. ولكن إذا احتاج مطور التطبيق إلى كتابة الكثير من النماذج المعيارية "غير الضرورية" للحصول على شيء يعمل ، فإن التأثير غير مرغوب فيه.

اعتمادًا على الزاوية التي ينظر فيها الأشخاص إلى مشكلة معينة ، قد تبدو المقايضة / التوازن مختلفة. قد يؤدي عدم توفير أدوات مناسبة أو ميزة معينة إلى جعل التنفيذ الداخلي لإطار العمل يبدو أكثر نظافة ، ولكنه يؤدي فقط إلى تفريغ المسؤولية عن مستهلك الإطار ، مما يجعل التنفيذ من جانب العميل أكثر تعقيدًا وإخفاقًا مما يجب أن يكون ، وهذا بدوره لا يساعد في تكييف العطاء إطار العمل. بالنسبة لمطور التطبيق ، تعتبر الإنتاجية والاتساق أمرًا مهمًا ، فإن اتباع نهج / معيار موحد مهم للعمل الجماعي والمجتمع. يجب أن ينظر النهج الشامل دائمًا إلى الأشخاص الذين يعيشون في الجانب الآخر من السياج.

يجب أن تكون الخطافات سهلة التنفيذ ، لكن الأدوات الوظيفية أصعب. قد يتطلب ذلك أنواعًا من الاتحادات في Dart لأنك تحتاج إلى التعبير عن شيء مثل:

القطعة | وظيفة القطعة (BuildContext) '.

الحاجيات الوظيفية أصعب. قد يتطلب ذلك أنواع الاتحاد في Dart

هذا بعيد عن أن يكون كافيا.
لا يزال هناك سؤال:

  • كيفية تمرير المعلمات إلى الوظائف؟ كاري؟
  • مرة واحدة في شجرة عناصر واجهة المستخدم ، يجب أن يكون لأثنين من عناصر واجهة المستخدم الوظيفية نوع وقت تشغيل مختلف
  • كيفية توصيل الحاجيات باستخدام devtools؟ (طريقة الأدوات debugFillProperties )

لقد فكرت في الأمر لبعض الوقت. لا أرى أي حل سهل للحاجيات الوظيفية.
الشيء الوحيد الذي يمكنني التفكير فيه هو مزيج من المكونات الإضافية لإنشاء الكود والمحلل (للحصول على تعريف مناسب وأشياء).

في الواقع ، جعلنا جزء إنشاء الشفرة نتخلى عن حزمة Functional_widget الخاصة بك. إنه يخلق فقط الكثير من القفز عند مراجعة التعليمات البرمجية. لذلك ، هذا لن يطير من أجلي ...

إنه يخلق فقط الكثير من القفز عند مراجعة التعليمات البرمجية

ولهذا السبب ذكرت مكونًا إضافيًا للمحلل.

باستخدام ملحق محلل مخصص ، يجب أن نكون قادرين على:

  • تحقق من أن الوظيفة لا تُستخدم مباشرةً وأن الفصل مفضل
  • لديك "انتقل إلى التعريف" / "نظرة خاطفة" / ... ، بحيث يؤدي النقر فوق الفصل إلى إعادة التوجيه إلى الوظيفة

هذا يجب أن يصلح جميع القضايا.
لكننا سنعود إلى "الخطافات تحتاج إلى نظام ملحق محلل مناسب".

ربما لا يلزم تقديم أدوات functional :

لنفترض أن استخدام الخطافات مسموح به فقط داخل طريقة StatelessWidget build .

من وجهة نظر فنية - لا يهم حقًا (بقدر ما أستطيع التفكير الآن) ما إذا كانت الفئة أو الوظيفة. الجزء المهم هو أنك لا تخلط بين الفئات ذات الحالة العامة والخطافات. تحت الغطاء ، لا يزال بإمكان عارض الرفرفة عد الخطافات وترتيبها إذا تم استدعاؤها داخل طريقة build وإدارتها بشكل صحيح.

في المستقبل ، إذا كان إنشاء عناصر واجهة مستخدم وظيفية ممكنًا ، فلن يكسر التغيير. أيضًا ، سيكون متوافقًا مع الجزء الخلفي ، لأنه لا يكسر التطبيقات الحالية.

لا أرى أي مشكلة واضحة في استخدام الخطافات داخل StatelessWidget من شأنها أن تزيل فوائد استخدام الخطافات مثل التركيب.

ومع ذلك ، لست متأكدًا من كيفية مقارنتها بحالات مثل useCallback وما إلى ذلك من رد الفعل مقارنة بالقدرة على استخدام طرق المثيل على أي حال

إن الوسيطة "يجب أن نضيف هذا لأن مطوري React سيكونون غاضبين" غير صالحة. (انظر مناقشة 500+ تعليق JSX).

Flutter هو Flutter ، وله لغة خاصة وأنماط تصميم.
أعتقد أننا لا يجب أن نضيف أشياء إلى إطار العمل فقط من أجل جعلها أكثر دراية لمطوري React ، يمكنهم استخدام الحزمة إذا أرادوا ذلك.

قرأت المناقشة وأعتقد أن Hixie كمطور لإطار عمل رفرفة قد رأى جانبه من المشكلة (التنفيذ و ... الأشياء) وكان لديه منظور أقل حول كيفية تفكير مطوري تطبيقات flutter (وهم جمهوره المستهدف) ، واستخدامها في تطورهم.

بصفتي مطورًا لنظام Android ، واجهت مثل هذه المشكلة ، أحاول تطوير بنية خلفية رائعة لتطبيقاتي دون أي فكرة عن الكيفية التي سيختبر بها مستخدمو تطبيقي عندما يرون واجهة المستخدم القبيحة ويصعب عليهم فهم تجربة المستخدم.

كما قال الآخرون من قبل ، فإن الخطاف رائع. بغض النظر عمن يقدمها ، سواء أكان FB أو Apple.
إنه يعمل فقط. يفصل بين منطق الدولة ودورات حياتها. يمكننا أن نجعل بعض الخطافات الأخرى المفيدة فوق الأخرى ، ونشر عناصر واجهة مستخدم مستقلة ، و apis ، وأدوات ، ... من حالات التطبيق ، وإعادة استخدام العناصر التي تم إنتاجها مسبقًا في مشاريع أخرى ، ...

وأعتقد أنه إذا كان من الصعب إنشاء تطبيق بسيط بكلمة hello ، فلا يوجد pubspec.yaml يمكن مناقشته هنا.
ولكن نظرًا لأن StatefullWidget مهم جدًا للنظام البيئي للرفرفة ، فإن الخطافات وذات الصلة لها أهمية أكبر في مستقبل الرفرفة ونظامها البيئي ومجتمع مطوري الرفرفة.

فقط تخيل كيف سيكون تطوير تطبيق flutter أبسط ، ومقاومًا للأخطاء ، وسهل الفهم ، وقابل للتوسيع ، وقابل للقراءة ، وقابل للتصحيح ، ومحمول ، ... (أي رقيق جيد بالإضافة إلى القدرة هنا الثابتة والمتنقلة 😁) مع خطافات مدعومة مباشرة بالنواة (أو شيء من هذا القبيل) في المنتصف بين الأدوات الأساسية وبعض الأدوات المعقدة مثل المواد ، ...) الرسمية بشكل خاص.

لفهم وجهة نظري بشكل أفضل ، انظر إلى مدى فظاعة تطوير android باستخدام Java ومكتبات الدعم وكيف أن الهوى واللطيف مع Kotlin.
كما أنه يفتح الباب لأشياء جيدة أخرى مثل Coroutines و Flow و AndroidX + Kotlin ونظام واجهة المستخدم الجديد (Compose)
حتى أنها دفعت مجتمع جافا لبدء وتنفيذ عقود kotlin المستقبلية في البيئة الخاصة بهم.

لذا يرجى إسقاط أي مخزن مؤقت في الخطافات ، والرد والقيام بذلك فقط

عدم وجود دعم رسمي هو السبب الوحيد الذي يجعلني لم أتحول من رد الفعل الأصلي.

الخطافات تجعل الحياة أسهل بكثير لدرجة أنني لا أريد كتابتها بالطريقة القديمة مرة أخرى

جزء مذهل من "الخطاف الأصلي" هو أنه يمكننا نقل العديد من أدوات StatefulWidget الداخلية أو ... إلى هذا النموذج البسيط القابل للفهم.
كما أعلن فريق flutter عن منحنى Flutter و Dart لسهولة الاستخدام والفهم والتعلم السريع. كل هذه الأمور يمكن أن تكون صحيحة وأفضل مع الخطافات الأصلية.
والطريقة (initState / dispose / setState / build) ليست في هذا المسار. (قد نحتاجها في الواجهة الخلفية للنظام الأساسي ولكن ليس للمطورين الجدد أو حتى المصممين الذين يرغبون في استخدام الكود فقط لوصف أفكارهم (وليس المنطق المعقد))

قراءتي لهذا الموضوع أن هناك الكثير من الناس متحمسون لاستخدام الخطافات في Flutter ، وبعض الأسئلة المفتوحة بخصوص الخطافات:

  • تأثير / قياس الأداء - على وجه الخصوص ، كفاءة استدعاء الوظائف دائمًا مقابل رؤية تلك الحالة لا بأس من إعادة استخدامها دون استدعاء وظيفة جديدة.
  • القدرة (عدم القدرة؟) على اللعب بلطف مع المفاتيح العالمية و / أو التحرك بكفاءة حول الشجرة.
  • دعم المحلل / الوبر المخصص للخطافات.
  • القدرة على العمل أيضًا مع إعادة التحميل السريع كأدوات واجهة مستخدم قديمة ذات حالة / عديمة الحالة.
  • الحاجة المحتملة لإطار عمل إضافي API.

أنا متأكد من أنه يمكن التعامل مع كل هذه الأسئلة ، لكن معالجتها ليس بالأمر الهين. المشكلة ليست كثيرًا "يجب أن تكون الخطافات في إطار العمل أو يجب أن تعيش الخطافات في حزمة منفصلة." إلى حد ما ، تم اتخاذ هذا القرار بالفعل - لقد كان flutter_hooks متاحًا على pub.dev منذ أكثر من عام الآن ، ويبدو أنه حزمة شائعة. إن جعل flutter_hooks تجربة مصقولة حقًا سيتطلب بعض العمل والاستثمارات الكبيرة ، بما يتجاوز ما تم إنجازه بالفعل.

لقد تم بالفعل إنجاز الكثير من هذا العمل لفئات إطار العمل الأساسية ، واستغرق الأمر عدة فرق هندسية بالإضافة إلى العديد من المساهمين مفتوحين المصدر سنوات للوصول به إلى النقطة التي وصل إليها. في بعض الأحيان يبدو أن هناك وهمًا "إذا قمنا بدمجها في repo X ، فسيتم حل جميع الأشياء التي لم يتم حلها!" لكن الطريقة التي تحدث بها هذه الأشياء هي أن الأشخاص المتحمسين لها يقومون بعمل تنفيذها. لقد قام rousselGit بالكثير من العمل حول هذا بالفعل ، ويبدو أن العديد من المساهمين الآخرين لديهم أيضًا في مستودع الخطافات.

ما أحاول قوله باختصار هو - يمكن أن تعمل الخطافات بشكل رائع دون التواجد في مستودع Flutter ، حيث إن التواجد في مستودع Flutter لن يؤدي إلى تسريع حل مشكلاته العالقة ، وأن أي شخص وكل من يريد رؤية الخطافات تعمل في Flutter تم تمكينه تمامًا لتحقيق ذلك.

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

المشاكل التي تحلها هوكس هي:

  • إدارة الدولة التصريحية ورد الفعل.
    State أمر ضروري
  • تكوين الدولة لإصلاح جاف.
    يجب إنشاء كل وحدة تحكم XXController هذه + تحديثها + التخلص منها ولا توجد طريقة لتحليل هذا المنطق إلى عوامل.
  • سهولة القراءة ، لأنها لا تتضمن تداخلًا لا نهائيًا للوظائف / الأدوات لتحقيق تلك النتيجة

لكن الصيغة البديلة يمكن أن تكون:

class MyWidget extends HookWidget {
  const MyWidget({Key key, this.title}): super(key: key);

  final String title;

  Hook<Widget> build() hook* {
    final (flag, setFlag) = yield false;
    final (animationController) = yield* useAnimationController(duration: const Duration(seconds: 2));

    // TODO: do something with animationController
    return CheckBox(
      value: flag,
      onChanged: setFlag,
    );  
  }
}

Hook<AnimationController> useAnimationController({required Duration duration}) hook* {
  final (tickerProvider) = yield* useTickerProvider();
  final (animationController) = yield AnimationController(duration: duration, vsync: tickerProvider);
  animationController.duration = duration;

  return animationController;
}

يحقق هذا التأثير نفسه مثل flutter_hook ، ولكنه مستقل عن الرفرفة ومع عوامل التحسين المتعددة التي لا يستطيع flutter_hook القيام بها.

وهذا يسمح بشكل أساسي لأي شيء باستخدام الخطافات ، وليس الأدوات فقط.

هذه فكرة مثيرة للاهتمام. يبدو أن هناك طلبات متعددة لميزة اللغة هناك (شيء مثل defer من Go ، شيء مثل المدمر الحتمي من C ++ ، بعض القدرة على تكوين وظائف ضمنيًا في كائنات) - ولكن هذا ليس المكان المناسب حقًا لتتبع ذلك.

أعتقد أنه سيكون من المفيد تحديد نقاط الألم التي يواجهها الأشخاص من خلال عدم وجود شيء مثل الخطافات في Flutter ، وتقديم المشكلات على وجه التحديد حول هذا الألم دون اختيار حل للبدء به. ومع ذلك ، من الممكن تمامًا أن تكون بعض نقاط الألم هذه مجرد أشياء يفرضها إطار العمل من أجل تحقيق أهداف تتعلق بالأداء أو الجودة أو مقايضات قابلية الاستخدام (كما هو الحال في ، يمكننا أن نجعل نقطة الألم X أفضل في تكلفة جعل نقطة الألم Y أسوأ بكثير).

كما هي الآن ، سأغلق هذه المسألة. هناك حزمة جيدة تتناول هذا الحل المحدد ، والحل نفسه ليس شيئًا جاهزًا للاندماج في إطار العمل في حالته الحالية (للأسباب الموضحة أعلاه) ، وليس من الواضح ما إذا كان الحل سيكون حقًا حقًا. الاستفادة من الاندماج في إطار العمل.

تعمل dnfield Hooks بشكل جيد "كعائلة" ، فقط عندما تكون لديك جميع المجالات الرئيسية للمتطلبات المشمولة.

سيكون من غير المجدي استخدام خطافات الحالة إذا أصطدمت بالحائط عندما تحتاج إلى نوع من التأثيرات بعد تغييرات الحالة.

يتطلب أي ربط حسب التصميم تغييرات كبيرة داخل جوهر العارض أو إدخال نوع جديد من المكونات الأساسية.

مثل هذا الجهد لا يستحق كل هذا العناء لنوع واحد فقط من الخطاف (نقطة الألم) ، لذلك أقول إنه من المستحيل حل هذه المشكلة كمجموعة من المشكلات الأصغر. لا يستحق الخطاف المفرد التبديل من المكونات ذات الحالة وبالتأكيد لا يستحق إدخال تغييرات كبيرة في محرك العرض.

إذا كان المقصود من هذه المشكلة أن تقول "أريد أن يكون Flutter أشبه بـ React ولكن أيضًا مثل Flutter" ، لست متأكدًا من مدى قابليتها للتنفيذ - وربما لا تكون مشكلة GitHub هي الطريقة الصحيحة لتتبع مثل هذا الشيء على أي حال ، حتى لو منحنا مثل هذا الشيء فمن المنطقي تتبعه.

بعبارة أخرى: إذا كان هذا طلبًا لإعادة كتابة جوهر Flutter ، فهذه ليست الطريقة الصحيحة للتعامل معه. لست متأكدًا من الطريقة الصحيحة للتعامل معها ، ولكن من المحتمل أن تبدأ بمجرد إنشاء المستودع وبذل جهد هائل.

لدي شعور غريب عندما يتم تقديم الخطافات لأشخاص لا يعرفونهم ويحافظون على تقنيات أخرى.

يبدو أن الرد غالبًا ما يكون شيئًا مثل "إذا كنت تريد أن يكون X مثل React ، فاستخدم رد الفعل".

رأيي هو أن الخطافات هي حل عام للعديد من مشاكل الواجهة حيث تحتاج إلى إعادة استخدام منطق البيانات المعقد. إنها أشبه بفكرة يمكن استخدامها في أي تقنية.

ومع ذلك ، تتطلب الخطافات نوعًا من التبديل في التفكير في تدفق البيانات قبل أن تظهر قيمتها بشكل كامل. أعتقد أنه قد يكون مشكلة كبيرة عند "طلب" الخطافات في أطر أخرى.

أعتقد أن فريق React قام بعمل رائع في محاولة شرح الخطافات ، لكن ربما يخلق بعض المقاومة لأنه جعل الخطافات تبدو مرتبطة ارتباطًا وثيقًا بـ React.

أعتقد أن React يُذكر في كثير من الأحيان الخطافات التالية لمجرد أن هذا هو المكان الذي تم اختراعها فيه. تعتبر React أيضًا أفضل مصدر للمعلومات حول الخطافات (حتى الآن).

بشكل عام - سأصف "نقطة الألم" بأنها عدم القدرة على استخدام نمط تكوين لمنطق البيانات مباشرة في Flutter. الخطافات هي مجرد مثال على السماح بذلك.

أفهم أيضًا أن تقديم الخطافات مهمة ضخمة ويجب أن أقول إنني لست على استعداد للقيام بذلك.

أنا شخصياً لا أفهم حجة "حاول المجتمع إصلاح هذه المشكلة ، لذلك ليس علينا فعل أي شيء".

لا يعني الإصلاح المجتمعي أنه لا يمكن لـ Google القيام به بشكل أفضل.
خذ التعبيرات الموجودة داخل المجموعات كمثال.
يمكن للمجتمع "إصلاحه" عن طريق تفرغ الصف / العمود / ListView / ... لدعم null .
لكن جوجل أصلحته عن طريق تعديل اللغة.

أيضًا ، يقول Flutter نفسه: Flutter مستوحى من React.
يمكن ملاحظة ذلك من خلال كيفية استخدام جزء كبير من كيفية استخدام عنصر واجهة المستخدم بشكل أساسي في كيفية استخدام فئة React.

في حين أن هذا لا يعني أن Flutter يجب أن تتطابق مع React ، إلا أنني أتوقع أن يقوم فريق Flutter على الأقل بإلقاء نظرة فاحصة على تحديثات React ونظامها البيئي.
يجب أن يوفر هذا على الأقل إجابة أفضل عن سبب "أننا لا نريد خطافات في إطار العمل" بخلاف حجة المجتمع.

تضمين التغريدة

أنا شخصياً أجد Hooks API ، كما هو الحال في React ، نوعًا ما يصعب فهمه. أفضل طرق دورة الحياة وتسميتها الوصفية.

أعلم أن هذه "مشكلة أنا" ، لكنني أؤيد تعليق dnfield قائلاً إنه ربما ينبغي علينا التعامل مع المشكلات وتنفيذ الحلول بشكل مختلف.

كما أنني نادرًا ما أتيت إلى موقف تحتاج فيه دجتان منفصلتان لمشاركة نفس المنطق (هذا ما فهمته على أنه فائدة رئيسية للخطافات؟)

وبشأن كون Flutter مستوحى من React ، فلا بأس بذلك ، لكن هذا لا يعني أنها ستتبع جميع أنماط React والهندسة المعمارية إلى الأبد.
إحدى المشاكل الرئيسية التي واجهتها مع React هي وجود العديد من الطرق المختلفة لفعل شيء ما ، وتغيير "الممارسات الموصى بها" يوميًا. أتفهم أنها طبيعة هندسة البرمجيات ، لكنني ما زلت أعتقد أنه إذا كان هناك شيء سيء بشأن الطرق الحالية ، فيجب محاولة تحسينها ... بدلاً من تكديس طرق مختلفة لتحقيق نفس الشيء.

آمل أن يقدم لك هذا منظورًا مختلفًا قليلاً ولا يسيء إلى أي شخص.

احترام كبير لمساهماتك في مجتمع Flutter.

حزين تم إغلاق هذه القضية. يجعل الأمر يبدو أن فريق Flutter يجهل الخطافات أو لا يهتم بالحالة الحالية لأنماط التصميم (آمل ألا يكون الأمر كذلك). هذا ليس جيدًا لأي تقنية ، فالأشخاص الذين يستثمرون مئات الساعات يريدون أن يعرفوا أن ما يستخدمونه هو من الدرجة الأولى ، ويمكن أن يكون على قدم المساواة معه ، والآن النمط الأكثر إنتاجية هو الخطافات و Flutter يتخلف عن الركب ، ولكن حتى أنه لم يتم النظر فيه أو تجاهله لصالح بديل أفضل بشكل مقنع من قبل القائمين على الصيانة.

cgarciae ، لا أحد يجهل ، قال dnfield بوضوح - بدلاً من محاولة الضغط على الحلول الحالية ، افتح المشكلات المتعلقة بالمشكلات المقابلة لديك ، سيقوم فريق Flutter بتقييمها وربما التوصل إلى حل يناسب Flutter بشكل أفضل.

هذه ميزة كان المجتمع يطالب بها بشدة وسيطلبها. إذا لم تكن المشكلة هي المكان المناسب ، فهل لديكم طلب ميزة لتسجيل المتطلبات من المجتمع؟

SpajicM أنا بخير تمامًا مع "لا" كإجابة.
ما لا أتفق معه هو التبرير الحالي.

بعض الملاحظات:

  • الخطافات هي سمة مهمة في React ، والد Flutter
  • هذه القضية هي واحدة من أكثر القضايا التي حظيت بالتأييد على Flutter
  • flutter_hooks تحظى بشعبية كبيرة
  • اقترح دان أبراموف من فريق React المناقشة مع الفريق https://github.com/flutter/flutter/issues/25280#issuecomment -456404333

يجب أن تعطي هذه بعض المناقشات المكثفة حول الخطافات. ليس بالضرورة تنفيذها ، ولكن على الأقل استكشافها.

في النهاية ، يتلخص الأمر في مشكلة الاتصال.

  • هل اتصل فريق Flutter بفريق React كما عرضه Dan Abramov؟
  • هل قام الفريق بتجربة الخطاف في React؟
  • هل تم النظر في بديل للمشكلات التي يحلها هوكس؟

نحن ، كمجتمع ، لا نعرف شيئًا عن ذلك.

إذا تقدمت خطوة إلى الأمام ، أعتقد أنه من المفارقات أن يُقترح على المجتمع تقسيم هذه المشكلة إلى "ما هي المشكلات التي يحلها الخطاف" ، عندما عرض فريق React نفسه شرح لفريق Flutter ما هي هذه المشكلات.

rousselGit أعتقد أن الفكرة وراء ذلك هي سماع المشكلات من الجانب الخاص بـ Flutter ، مباشرة من المستخدمين ، واتخاذ ذلك كنقطة بداية بدلاً من اتخاذ استدلال React ، وهذا لا يعني أن مدخلاتهم لن تكون ذات قيمة.

رأيي أنه سيكون من الجيد أن يكون لديك طريقة للفصل بوضوح بين منطق وتصميم الأداة - لذلك أوافق على أن هناك مشكلة يجب حلها ، ولكن الطريقة التي يتعامل بها React مع ذلك أمر محير إلى حد ما بالنسبة لي وأتمنى أن يكون لحل Flutter في المستقبل تغيير نموذج أقل دراماتيكية / منحنى التعلم. ليس لدي فكرة في ذهني ولكني متأكد من أن المجتمع مع الفريق يمكن أن يأتي بشيء ما إذا كان منفتح الذهن وغير مُركّز على تنفيذ الخطافات الحالي.

أعتقد أن الخطوة التالية هي فتح مشكلة تسمى:

_ "يحتاج Flutter إلى طريقة أفضل لعزل منطق عنصر واجهة المستخدم" _

أعتقد أن https://svelte.dev/ لديه نهج مختلف وأفضل لحل هذه المشكلات. كخطوة أولى ، يجب أن يدرك فريق Flutter أن هناك مشكلة وأننا بحاجة إلى حل.

أنا جديد في الرفرفة وما أشعر به هو أن واجهة برمجة التطبيقات لديها الكثير من النماذج المعيارية. لدى Thought Dart عام ، يبدو الأمر كما لو كنت أبرمج في Go حيث يكون النسخ واللصق أكثر شيوعًا / أسهل. آمل أن تكون هناك عملية إعادة بناء ضخمة عندما هبطت NNDB ، خاصة باستخدام طريقة التمديد إلى أقصى حد. قد يكون التجريد التدريجي لواجهة برمجة التطبيقات عبر شيء مثل طريقة الامتداد أمرًا يستحق الاستكشاف.

IMHO ، فريق Flutter حريص جدا على فكرة "كل شيء هو القطعة". تعتبر الأدوات الذكية رائعة للعناصر والتخطيطات المرئية ، ولكن ليس للحصول على البيانات / معالجتها. بدلاً من FutureBuilder ، StreamBuilder ، TweenAnimationBuilder إلخ. أفضل واجهة برمجة تطبيقات وظيفية:

Widget build(BuildContext context) {
    final a = useFuture(someFuture);
    final b = useStream(someStream);
    if (a.value == null || b.value == null) {
        return CircularProgressIndicator();
    }

    final value = a.value + b.value;
    final smoothedValue = animate(value, duration: Duration(milliseconds: 100), curve: Curves.easeInOut);

    return Slider(
        value: smoothedValue
    );
}

في الواقع ، يستخدم Flutter بالفعل خطافات في بعض الأماكن. لذا بدلاً من المزيد من "Fluttery"

MediaQueryGetter {
    builder: (BuildContext context, MediaQueryData data) {
        ...
    }
}

يمكنك استخدام
final data = MediaQuery.of(context);

لسوء الحظ ، تعمل هذه الآلية (الاشتراك أثناء الحصول) فقط مع InheritedWidget.

لست متأكدًا من مقدار التقدم الذي يمكننا إحرازه في هذا الأمر ، لكنني أردت تناول بعض النقاط التي أراها هنا:

  1. إن تقييم الحل أصعب بكثير من تقييم مشكلة في مشكلة GitHub. عندما تقدم حلاً ، هناك حد أعلى بكثير للوصول إلى القبول. عليك أن تُظهر أن الحل جيد التكوين ، ويستحق الجهد الذي يستلزمه ، وأنه يحل مجموعة من المشكلات الحقيقية التي تتناسب مع مستوى الجهد الذي يتطلبه (بما في ذلك ليس فقط النماذج الأولية والتنفيذ ، ولكن أيضًا التحكم والجودة المستمرة) . بعبارة أخرى ، من المحتمل أن تؤدي المشكلة التي نناقش فيها نقطة ألم معينة حول إدارة البيانات وحالة عنصر واجهة المستخدم إلى عدد من الحلول ، يمكن اعتماد بعضها في إطار العمل ، وبعضها يمكن أن يصبح حزمًا تابعة لجهات خارجية ، وبعضها الذي سيكون لطيفًا ولكنه يكلف كثيرًا.

  2. يسعى مهندسو Google الذين يعملون في Flutter و Dart دائمًا إلى تحسينه ، وهم دائمًا مشغولون بشكل عام. وينطبق الشيء نفسه على العديد من المهندسين الذين لا ينتمون إلى Google والذين يساهمون في Flutter. لا يعني إغلاق هذا الخطأ أنه لن يعمل أي مهندس في Google على الإطلاق على جعل الخطافات تعمل بشكل أفضل مع Flutter. حقيقة أن حزمة الخطافات مملوكة لأحد أعضاء المجتمع لا تقلل بطريقة ما من جودة الحزمة أو قيمتها - ولا تقلل من القدرة على مواجهة بعض أوجه القصور المحددة في هذا الخطأ ، على سبيل المثال دعم أفضل للتحليل / الفحص

  3. هناك أسباب مختلفة لقبول أو رفض الميزة. في بعض الأحيان تكون الميزة رائعة حقًا ، ولكنها لا تتناسب تمامًا مع الهندسة المعمارية. في بعض الأحيان ، تبدو الميزة جيدة على السطح ، ولكن بها بعض أوجه القصور الرئيسية التي لم تعالجها. في بعض الأحيان تكون الميزة رائعة ، وتتناسب مع قدر كافٍ من الجهد ، لكن مقدار الجهد الذي تكلفه يفوق القيمة التي تقدمها للمستخدمين ، أو قد يبتعد عن الوقت اللازم لميزات أخرى أكثر قيمة. بالنسبة إلى Flutter على وجه الخصوص ، في بعض الأحيان يكون لدينا بنية ذات طبقات عالية تمكن من التمديد بواسطة حزم الطرف الثالث ، وفي كثير من الأحيان يكون من الأفضل الحفاظ على الوضع والسماح للأطراف الثالثة بالقيام بعمل رائع بدلاً من تضمين بعض الأشياء الجديدة في إطار العمل. نقوم بذلك بأنفسنا في حزم مثل حزمة الرسوم المتحركة الجديدة التي تعيش على https://github.com/flutter/packages/tree/master/packages/animations.

أخيرًا ، كنت على الطرف الآخر من هذا. أنا مسؤول عن صيانة الحزمة بنفسي ، وقد تم رفض مقترحات الميزات التي كان من شأنها تسهيل صيانة الحزمة الخاصة بي أو تطويرها. نصيحتي الوحيدة هي أنه إذا كان لديك حزمة رائعة تحبها ، فاستمر في العمل عليها. سيتعرف عليه الأشخاص الآخرون ويساعدون أيضًا ، سواء تم تضمينه في هذا الريبو أم لا.

يحتوي تطبيق ComposeUI الجديد في Android على حالات ربط مثل: (معاينة 2)

val state = remember { CardDesignerState() } // react: let state = useState(CardDesignerState())
val thing = stateFor<T?> { null } // react: let thing = useState()

يحتوي SwiftUI الجديد على نظام iOS أيضًا على أشياء مماثلة (لكنه داخليًا):

// from https://developer.apple.com/tutorials/swiftui/animating-views-and-transitions
Image(systemName: "chevron.right.circle")
                        .imageScale(.large)
                        .rotationEffect(.degrees(showDetail ? 90 : 0))
                        .scaleEffect(showDetail ? 1.5 : 1)
                        .padding()
                        .animation(.easeInOut)

تخيل استخدام واجهة المستخدم السريعة لنظام iOS onCreate، onInit، onUpdate، onExit، ... 🤢

لكن أفضل إطار عمل (بالطبع هو Flutter) لا يزال يقاوم فكرة استخدام الخطافات ، لماذا؟
لأنها تبدو تحب React / ReactNative !!! أو بعض الاقتباسات المذهلة من فريق المشرف:

أنا أفضل أن أرى النموذج المعياري

من الواضح أنه ضد فكرة الرفرفة لكتابة واجهة المستخدم مع بناء الجملة التعريفي

أعتقد أن هوكس ميكسين هو حل جيد.
احصل على خطافات في أي مكان نحبه ولا تلمس أكواد وإطار عمل المطورين من الطراز القديم.
لكن هذه الفكرة وأي أفكار رائعة أخرى تحتاج إلى تكامل كبير مع المكتبات الأساسية ومن الجيد أن ترى المشرفين الأساسيين يدعمون هذه الميزات من الدرجة الأولى.
كما يمكنني أن أتخيل مستقبلًا بعد تكامل الخطافات ، حيث تدعم العديد من مكتبات إطار العمل عالية المستوى (مثل المواد) بشكل كبير وحتى استخدامها فيها.

يمكن أن يكون الرفرفة أجمل:

// this is just scratch, not a complete and true use-case
build(context) {
    final angle = useAnimation(2*PI, 0, 5 /*seconds*/);
    return Image.from(myAwesomeImage)
        .padding(8)
        .scale(2.5)
        .rotate(angle);
}

HKhademian أتفق تماما. إن عدم وجود دعم من الدرجة الأولى لأي شيء يشبه الخطاف (أو بعبارات أخرى - أي شيء يسمح بالتكوين المناسب لمنطق العمل القابل لإعادة الاستخدام) هو في الواقع السبب الوحيد لعدم اختيار Flutter لمشروعي الأخير.

2. حقيقة أن حزمة الخطافات مملوكة لأحد أعضاء المجتمع لا تقلل بطريقة ما من جودة الحزمة أو قيمتها - ولا تقلل من القدرة على مواجهة بعض أوجه القصور المحددة في هذا الخطأ ، على سبيل المثال تقديم دعم أفضل للتحليل / فحص

هل أعضاء المجتمع حزم أشباح؟ نعم. هل ستعمل Google على شبح Flutter؟ حسنًا ، بناءً على موقفك هنا يبدو أنه يجب أن يكون احتمالًا. التأكيد على أن الأساسي Flutter قابل للتطبيق للاستهلاك مثل حزم المجتمع ... خطأ في أحسن الأحوال وكذبة في أسوأ الأحوال.

علاوة على ذلك ، فقد ثبت مرارًا وتكرارًا أنه ما لم يكن هناك شراء من Hixie ، الذي أظهر تقاربًا لاستخدام التفضيل الشخصي لتجاوز طلبات المجتمع ، فلا يهم ما يريده المجتمع أو يحتاجه. بدون شراء في ، لا يحدث ذلك. وإذا لم يكن الأمر كذلك ، فإن عملية القرار غامضة للغاية بحيث لا يمكن رؤية خلاف ذلك.

ما يثير اهتمامي هو أن الأشخاص الذين يقررون ما إذا كانت الميزات تعيش أو تموت يبدو أنهم يتمتعون بخبرة عمل قليلة جدًا في إنشاء تطبيقات الأجهزة المحمولة. ستعطي وجهة النظر هذه دائمًا أكبر قدر من الأفكار حول السكر الذي يجب مزجه في Flutter.

أعتقد أننا بحاجة إلى عملية رسمية لتحديد الميزات التي تجعلها في Flutter والتي تضع وزنًا أكبر على المجتمع للمساهمة في عملية صنع القرار. من الواضح أنه ليس بنسبة 100٪ ، لكن في الوقت الحالي يبدو الأمر وكأنه يمثل حوالي 5٪ ، و 5٪ متقشر للغاية عند ذلك. تضمين التغريدة

إن تقييم الحل أصعب بكثير من تقييم مشكلة في مشكلة GitHub

عرض فريق React شرح أسبابهم وراء الخطافات في بداية هذه المشكلة.
يجب أن يغطي هذا بشكل كامل الحاجة إلى شرح سبب الحاجة إلى الخطافات ، حيث لا يوجد أحد في وضع أفضل لشرح الخطافات من فريق React أنفسهم.

مشكلة ذات صلة (وصفية) https://github.com/flutter/flutter/issues/28884

لوقا ، أنا أحترم وأقدر شغفك ، لكن من فضلك توقف عن هجمات ad hominem. نحن نعمل جميعًا لمحاولة بناء أفضل منصة ممكنة ، وإجراء جميع أنواع المقايضات بناءً على قدرة الموارد ، وبحث المستخدم ، ومدخلات أصحاب المصلحة ، واحتياجات العملاء ومدخلات المجتمع.

كن لطيفا من فضلك. https://github.com/flutter/flutter/blob/master/CODE_OF_CONDUCT.md

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

يجب أن يجتمع الأشخاص الذين يختلفون معًا ، ومحاولة فهم وجهات نظر بعضهم البعض ، والعمل على إيجاد تصميم يعالج مخاوف الجميع.

هل كان هناك أي تحديث حول هذا الأمر ، أو أين يمكننا تنسيق الحل؟ أواجه هذا الأمر من خلال مشاريع Flutter ، خاصةً مع الرسوم المتحركة والانتقالات. تساعد الخطافات على تغليف هذه الحالة initState و dispose ، من بين أمور أخرى ، في وظيفة واحدة واستخدام هذه الوظيفة فقط بدلاً من إعداد كل شيء.

يبدو ، على الأقل بالنسبة للمراقب الخارجي / مستخدم Flutter بدلاً من مشرف البرنامج الإضافي ، أن هناك مخاوف مشروعة لا تشعر أنه يتم الاستماع إليها ، مثل المشكلة الأخرى المتعلقة بـ Flutter Overlays (# 50961 ) ، ويبدو أنه تم استبعادها على أنها ليست مشاكل حقيقية للمستخدمين ، وليس للقائمين على الصيانة. مرة أخرى ، لا يوجد ازدراء للمشرفين ، هذا مجرد رأيي لأن شخصًا ما يقرأ موضوع المشكلة هذا بشكل عرضي ، فأنا لست على دراية بأية مشكلات أخرى قد تكون مختلفة.

مع ما يقال ، كيف يمكننا المضي قدمًا بشكل عام في التفكير في حلول للمشاكل التي يبدو أن المستخدمين يواجهونها بشكل شرعي؟ أعلم أن Rust لديه نظام RFC مثير للاهتمام يبدو أنه يعمل بشكل جيد لتصميم حلول جديدة.

satvikpendem عملية RFC هنا هي تقديم خطأ يصف المشكلة ، وبعد ذلك بمجرد وصف المشكلة بوضوح ، لمناقشة الحلول الممكنة.

يبدو أنه تم شرح المشكلات حتى الآن ، لذا يمكن مناقشة الحلول الآن ، وفقًا لتعليقك. ماذا يمكننا أن نفعل بعد ذلك ، هل هناك حلول أخرى تعمل بشكل أفضل من الخطافات أو شيء مشابه؟

إذا سمحت لي بمعرفة الخطأ # يمكنني إخبارك إذا كانت المشكلة تصف مشكلة بتفاصيل كافية تجعل من المنطقي البدء في مناقشة الحلول الممكنة.

hixie https://github.com/flutter/flutter/issues/51752

أعتقد أيضًا أنه يجب علينا متابعة تعليق دان: https://github.com/flutter/flutter/issues/25280#issuecomment -456404333
ماذا كانت نتيجة هذا النقاش؟

مرحبًا ريمي ، شكرًا جزيلاً على الخطأ رقم 51752. أعلم أنك استثمرت الكثير من الوقت في هذا المكان وساهمت بحزم عالية القيمة هنا. شكرا لك x1000 على هذا!

لتكرار تعليق dnfield ، يبدو أننا لم نلتف بعد حول مساحة المشكلة وأهميتها. الخطأ أعلاه هو خطوة مفيدة نحو هذا الهدف ، و / أو في مناقشة الأساليب المحتملة للمشكلة. يفترض سؤال المتابعة الخاص بك هنا أن المحادثة مع فريق React هي الخطوة الأولى من هنا ، ولكن إذا لم يكن لدينا حتى الآن محاذاة في مساحة المشكلة ، فهذا يبدو سابقًا لأوانه.

ربما يمكننا عرض أمثلة كاملة للتطبيقات التي بها مثل هذه المشكلات التي يمكن إصلاحها باستخدام الخطافات. لن نعيد كتابتها بالضرورة بخطافات ولكن فقط نعرض مقدار لصق النسخ الموجود. هل سيكون هذا شيئًا قابلاً للنقاش ،timsneath؟ أو هل ستفكر في شيء آخر؟ أحاول معرفة كيفية إظهار مساحة المشكلة بأكبر قدر ممكن من الوضوح.

: موجة:timsneath
لأكون صريحًا ، لا أفهم تمامًا سبب كون المناقشة مع فريق React سابقة لأوانها.

حتى بدون طلب المجتمع للخطافات ، ستظل المناقشة مع فريق React ذات قيمة كبيرة.
تشترك React في الكثير من أوجه التشابه مع Flutter ، ولديهم بضع سنوات إضافية من الخبرة في التعامل مع كائنات تشبه الأدوات.

يمكن للمناقشة معهم أن تعود بالفائدة على كلا الطرفين فقط.

كمثال:
بعد إنشاء flutter_hooks ، اتصل بي دان لمناقشة كيفية تعاملي مع إعادة التحميل السريع للخطافات.
كانت إجابتي "لم يكن هناك شيء تقريبًا أفعله لأن Flutter يستخدم لغة مكتوبة".
بعد بضعة أشهر على الطريق ، قاموا بتحسين إعادة التحميل السريع لـ React من خلال إنشاء شيء مشابه للأنواع مع Babel

أنا متأكد من أنه إذا ناقش فريق Flutter و React ، يمكن أن تحدث العديد من مثل هذه التفاعلات ، وستتقدم التقنيتان.

بعض الأسئلة المفتوحة التي يمكن طرحها بدون مشكلة معينة:

  • لماذا هوكس؟
  • لماذا وضع التشويق / المتزامن؟
  • لماذا البوابات؟

satvikpendem عملية RFC هنا هي تقديم خطأ يصف المشكلة ، وبعد ذلك بمجرد وصف المشكلة بوضوح ، لمناقشة الحلول الممكنة.

هل هذا يعني أنه يتم تجاهل أي مناقشات لا تعتبر خطأ؟ اعتقدت أن الغرض من RFC هو الأشياء التي ليست أخطاء ، ولكن عادةً لتوسيع أشياء أكثر ذاتية مثل تجربة المطور أو دلالات الأدوات.

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

أنا متأكد تمامًا من أن أحداً لم يقل "سيتم تجاهل المناقشات التي لا تعتبر خطأً". تعال ، فلنعمل معًا بحسن نية ، ونعامل بعضنا البعض باحترام ولطف. نحن جميعًا نبذل قصارى جهدنا هنا ، ولكن مع وجود الكثير من الأخطاء والتصميمات والأفكار المنافسة الأخرى التي تتنافس على اهتمامنا :)

lukepighetti ، من سخرية القدر ، "يجب أن يكون لدينا خطافات لأن أطر العمل الأخرى بها" هو بالضبط نوع المحادثة التي نحاول تجنبها ، في الواقع - لأنه يؤدي إلى تصميم تم تحسينه بحكم التعريف لاحتياجات أطر العمل الأخرى. من المفيد حقًا في العملية وصف المشكلة التي نحاول حلها في سياق Flutter ، لأن ذلك يساعدنا جميعًا في الاتفاق على ما إذا كانت المشكلة هي نفسها أم لا ، وما إذا كان الحل يجب أن يكون هو نفسه ، وما إلى ذلك.

rousselGit - بالتأكيد ، هناك بعض المحادثات العامة المفيدة التي يمكن أن نجريها مع فريق React. أرحب بالعرض ، وربما ينبغي أن نفعل ذلك في مرحلة ما. لديهم الكثير من الذكاء في هذا الفريق ، بالتأكيد ، وعرضهم كريم ولطيف للغاية. في الوقت الحالي ، نتحدث معهم بشكل أساسي لأنك أخبرتنا بذلك ، وليس لأن لدينا أسئلة محددة تم إبلاغنا بما يكفي لمناقشتها :)

وأيضًا ، مجرد تذكير: "فريق Flutter" هم فقط الأشخاص الذين يساهمون في Flutter. يعمل بعض المساهمين في Google ، ويلعب بعض المساهمين دورًا أقوى في إدارة بنية المشروع ، ولكنك أيضًا عضو في فريق Flutter مثل أي شخص آخر يساهم في المشروع :)

كما هو الحال دائمًا - شكرًا لك - على صبرك في مناقشة هذا الأمر ، وعلى مساهماتك في المجتمع ، لمواصلة دفع المشروع إلى الأمام بأفكار إبداعية في هذا المجال!

للتوضيح ، "خطأ" كما نستخدمه هو مصطلح عام يشير إلى أي شيء قد يؤدي إلى تغيير. يمكن أن تكون حالة استخدام ، يمكن أن تكون فكرة ، يمكن أن تكون خطأ منطقي ، يمكن أن تكون خطأ مطبعي في الوثائق ، شيء محير على موقع الويب ، أيا كان.

ربما يمكننا عرض أمثلة كاملة للتطبيقات التي بها مثل هذه المشكلات التي يمكن إصلاحها باستخدام الخطافات. لن نعيد كتابتها بالضرورة بخطافات ولكن فقط نعرض مقدار لصق النسخ الموجود.

satvikpendem إذا كانت المشكلة "يحتوي التطبيق الخاص بي على الكثير من النصوص المعيارية" ، فهذا بالتأكيد خطأ يجب عليك تقديمه ويمكننا مناقشة كيفية تحسين الأمور. اذكر الخطأ # هنا حتى نتأكد من استمرار المحادثة في الخطأ الخاص بك.

شكرا للتعليق @ Hixie. تتم تغطية مشكلتي على نطاق واسع بنفس الخطأ الذي ذكره rousselGit (# 51752) لذلك لا أعتقد أن لدي المزيد لإضافته بناءً على ما قرأته في هذا العدد.

timsneath لست متأكدًا من فهمي لتعليقك على lukepighetti ، كما هو الحال في ، يبدو الأمر وكأننا وصفنا المشكلة في سياق Flutter عدة مرات مختلفة ، مثل هذه المشكلة ، # 51752 ، وغيرها. ما الذي نحتاج إلى تضمينه أيضًا؟ كيف يمكننا مساعدتك في أن تكون أكثر إطلاعًا على مساحة المشكلة هذه بحيث إذا تحدثنا إلى فريق React أو غيره ، فستكون لديك معرفة كافية لطرح أسئلة مستنيرة ، كما تقول؟

أوافق على أنه لا ينبغي لنا نسخ أشياء من أطر أخرى لمجرد أن React بها ، على سبيل المثال ، لذلك قد يكون من المفيد رؤية حلول أخرى لمشكلة تكرار الكود. نشر مؤسس Vue @ yyx990803 بعض أفكاره في Vue's RFC (https://www.github.com/vuejs/rfcs/tree/function-apis/active-rfcs٪2F0000-function-api.md) والتي ستكون مفيدة من خلال الذهاب الى. من المفيد قراءة نظرة خاصة على الأقسام المتعلقة بالمشكلات التي يتم حلها ولماذا يختلفون باحترام حول واجهة برمجة التطبيقات القائمة على الفصل.

شكرًا لتوضيح Hixie ، لقد أساءت فهم هذا التعريف الأوسع (ربما الداخلي؟) لـ "الخطأ".

timsneath لست متأكدا من أن أتابع. مجموعة أخرى من الأشخاص ، مطوري التفاعل الأساسي ، حددوا بالفعل مجموعة من المشكلات وأبلغوا عنها ، وخلقت حلاً في إطار معماري مماثل ، والعديد من فرق الواجهة الأمامية عبر أطر عمل متعددة تبلغ عن النجاح. لا أرى أي مؤشر على أن هذا هو "حل قبل مشكلة" مشكلة جيثب. يبدو أن Hixie لا توافق على أن هناك مشكلة يجب حلها ، ويبدو أن هذا يعتمد على خيارات الأسلوب أو الصيانة التي لا تعكس فوائد تجربة المطور. أقول ذلك بأقصى درجات الاحترام أثناء محاولتي فهم مصدر الإحجام عن طلب التعليقات هذا.

لا أوصي عادةً بميزات الببغاء ، لكن RFC للخطافات لا يخلو من التقنية السابقة مع تبرير جيد. التقنية السابقة متاحة من فريق رد الفعل الأساسي ، وأي مبرر نتوصل إليه هو تكرار ما يمكنهم وما نقلوه. يبدو أن rousselGit يدافع عنكم يا رفاق لإعداد اجتماع معهم لمناقشة هذا الموضوع ، حيث يمكنهم تقديم رؤى أكثر بكثير مما نستطيع في قضية GitHub.

كقضية تعريفية ، بالنسبة لي شخصيًا ، سيكون من المفيد إذا كانت هناك عملية ملموسة لتضمين RFCs واسعة النطاق في خارطة طريق flutter/flutter التي يقدمها المجتمع. لدينا مقولة مفادها أن أصحاب المصلحة الخارجيين هم من يريدون العمل الصعب والضروري ، ولهذا السبب يجب إشراكهم وأخذهم على محمل الجد. خارجي في سياق flutter/flutter سيكون غير فريق ، وليس google ، وليس GDE.

لقد قمت بتوثيق عملية RFC الخاصة بنا على موقع wiki الخاص بنا.

الخارجية في سياق الرفرفة / الرفرفة ستكون غير جماعية ، وغير تابعة لـ Google ، وغير تابعة لـ GDE.

بحكم التعريف ، إذا كنت ترسل طلب تقديم طلب (RFC) ، فأنت عضو في الفريق.

تتم تغطية مشكلتي على نطاق واسع بنفس الخطأ الذي ذكره rousselGit (# 51752)

في هذه الحالة أوصي بالمشاركة في هذه المناقشة ؛ هذه المشكلة بالذات مغلقة ولكن هذا واحد مفتوح. كان هناك عدد قليل من الأوصاف للمقترحات في هذه القضية ، على الرغم من أن أيا منها لا يبدو أنها تقوم بعمل جيد. لم يكن هناك حتى الآن وصف واضح بشكل خاص لـ "الخطافات" هناك ، فقد تم ذكرها فقط بشكل عابر.

ما زلت لا أفهم لماذا يُتوقع منا شرح المشكلة عندما يتم توثيق كل من المشكلات والحلول المقترحة بوضوح شديد بواسطة React و Vue.

يحتوي RFC of hooks على حوالي 1400 تعليق ومقطع فيديو تقديمي ووثائق ومقالات من العديد من الأشخاص الأذكياء.

يمكننا أن نختلف على حل هذه المشاكل. لكن لا ينبغي أن تكون هناك حاجة لشرح المشاكل

تم شرح المشكلة في # 51752 ، أليس كذلك؟ أليست هذه هي المشكلة؟

(فيما يتعلق بالسبب: لأن توجيه فريق التطوير إلى RFC المكون من 1400 تعليق لمنتج مختلف ليس طريقة فعالة للتواصل مع فريق التطوير هذا. أنا آسف إذا شعرت أنني بليد.)

آسف لاختبار الاتصال الضخم. أردت فقط أن أقول لأي شخص يتابع هذا الأمر أنني تركت بعض الأفكار الأخرى من منظور React في https://github.com/flutter/flutter/issues/51752#issuecomment -665380355 وسيسعدني الإجابة المزيد من الأسئلة إذا كان ذلك سيكون مفيدًا.

أردت أيضًا أن أعبر عن أملي في أن هذا (والخيوط ذات الصلة) يمكن أن يظل متحضرًا ولا يضغط على المشرفين بحجج مثل "إنه يعمل مع React". توجد اختلافات كبيرة بين React و Flutter في نموذج البرمجة ، وتعتمد React Hooks بشكل خاص بشكل كبير على بعض الفروق الدقيقة الخاصة بنا. لديهم أيضًا بعض المراوغات كنتيجة قد لا يقبلها الكثيرون.

لقد غيرت رأيي في الخطافات. أعتقد أنها نموذج رائع ، لكنني انتهيت للتو من عقد React Native وقد أدت الخطافات (في رأيي) إلى تجزئة نظام التطوير بشكل رهيب لتحقيق مكاسب قليلة جدًا. يستخدم Flutter حاليًا نمطًا مشابهًا جدًا لمكونات فئة React وهناك الكثير من الأدوات المبنية حوله. إذا كان إطار العمل سيتحول إلى الخطافات كحل أساسي لإدارة الحالة ، فسيؤدي ذلك إلى كسر جميع أنماط العمل والعقلية الحالية التي يستخدمها مطورو Flutter لتحقيق مكاسب قليلة جدًا.

أعتقد أن هناك حجة مفادها أن الخطافات هي نمط متفوق للتنمية الإنتاجية ، لكنني أعتقد أن هناك حجة أكثر إقناعًا (مثل حجة dartfmt الأساسية) بأن الاتساق بمرور الوقت أفضل من "الأفضل".

يجب أن أشير أيضًا إلى أنه عند التعامل مع مطوري React الجدد ، غالبًا ما نواجه حواجز طريق مع خطافات تؤدي إلى نتائج غير متوقعة وعلينا تعليمهم استخدام مكونات الفصل أولاً. (المقارنة الجيدة هي أن المطورين الجدد لديهم وقت أسهل في استخدام حلقات for مقارنة بأساليب التجميع مثل الخريطة / تقليل / تصفية / طي). الخطافات هي نمط متقدم ونأخذ ذلك أحيانًا كأمر مسلم به. الشيء المحبط هنا هو أن مجتمع React يتخلص بسرعة من التوثيق والدعم لأنماط مكونات الفصل مما يجعل من الصعب تقديم هذا التعليم أو الخيار للمطورين الجدد.

لقد ذكرت في العدد الآخر رقم 51752 أنه ربما يتعين علينا العمل على إنشاء نسخة أكثر تحديدًا من Flutter من الخطافات ، حيث يبدو أن الخطافات نفسها بها بعض العيوب مثل نمط useEffect(() => ..., [] ) للعرض مرة واحدة فقط. ابتكرHixie إصدارًا مثيرًا للاهتمام باستخدام نمط Property and PropertyManager الذي يبدو أنه يفعل شيئًا مشابهًا للخطافات ولكن قد لا يحتوي على هذه العيوب. يجب أن ننظر أكثر في بدائل الخطافات لأنه ، على الأقل بالنسبة لـ Flutter ، يبدو أن هناك شيئًا يعمل بشكل أفضل من خطافات نمط React ولكنه لا يزال يحل نفس المشكلات.

هل كانت هذه الصفحة مفيدة؟
0 / 5 - 0 التقييمات