لف مكون رد الفعل المتحكم فيه ، للسماح بحذف أزواج دعامة/معالج محددة من قبل المستهلكين المكون. لا يمكن السيطرة عليها يتيح لك كتابة مكونات React ، مع الحد الأدنى من الحالة ، ثم لفها في مكون سيدير الحالة للدعامة/المعالجات إذا تم استبعادها.
npm i -S uncontrollable
إذا لم تكن متأكدًا بعض الشيء على سبب قراءة هذه الوحدة القسم التالي أولاً. إذا كنت ترغب فقط في رؤية بعض الأمثلة في العالم الحقيقي ، فتحقق من مصادر React التي تستفيد من هذه الاستراتيجية.
import { uncontrollable } from 'uncontrollable' ;
useUncontrolledProp(value, defaultValue, onChange) => [value, onChange]
خطاف رد الفعل الذي يمكن استخدامه بدلاً من مكون الترتيب الأعلى أعلاه. يعيد مجموعة كاملة من props
التي هي آمنة للانتشار إلى عنصر الطفل.
import { useUncontrolledProp } from 'uncontrollable' ;
const UncontrolledCombobox = ( { value , defaultValue , onChange } ) => {
// filters out defaultValue, defaultOpen and returns controlled
// versions of onChange, and onToggle.
const [ controlledValue , onControlledChange ] = useUncontrolledProp (
value ,
defaultValue ,
onChange
) ;
return < Checkbox { ... controlledProps } / > ;
} ;
useUncontrolled(props, propsHandlerHash) => controlledProps
خطاف رد الفعل الذي يمكن استخدامه بدلاً من مكون الترتيب الأعلى أعلاه. يعيد مجموعة كاملة من props
التي هي آمنة للانتشار إلى عنصر الطفل.
import { useUncontrolled } from 'uncontrollable' ;
const UncontrolledCombobox = ( props ) => {
// filters out defaultValue, defaultOpen and returns controlled
// versions of onChange, and onToggle.
const controlledProps = useUncontrolled ( props , {
value : 'onChange' ,
open : 'onToggle' ,
} ) ;
return < Checkbox { ... controlledProps } / > ;
} ;
واحدة من نقاط القوة في React هي نموذج تمديدها ، الذي يتم تمكينه من خلال ممارسة شائعة لدفع حالة المكون على ارتفاع الشجرة قدر الإمكان. على الرغم من كونها رائعة لتمكين مرنة للغاية وسهلة التفكير في المكونات ، إلا أن هذا يمكن أن ينتج عنه الكثير من الغلاية لتسجيل المكونات مع كل استخدام. بالنسبة للمكونات البسيطة (مثل الإدخال) ، عادة ما تكون هذه مسألة ربط value
الإدخال إلى خاصية حالة الوالدين عبر معالج onChange
الخاص بها. هنا نمط شائع للغاية:
render ( ) {
return (
< input type = 'text'
value = { this . state . value }
onChange = { e => this . setState ( { value : e . target . value } ) }
/ >
)
}
يحرك هذا النمط مسؤولية إدارة value
من المدخلات إلى الوالدين ويحاكي بيانات "اتجاهين". ومع ذلك ، في بعض الأحيان ، ليست هناك حاجة للوالد لإدارة حالة المدخلات مباشرة. في هذه الحالة ، كل ما نريد القيام به هو تعيين value
الأولية للمدخلات ودع الإدخال يديره من ذلك الحين. يتعامل React مع هذا من خلال مدخلات "غير خاضعة للرقابة" ، حيث إذا لم تشير إلى أنك تريد التحكم في حالة الإدخال خارجيًا عبر value
، فإنه سيؤدي فقط إلى الحفاظ على الدفاتر لك.
هذا نمط رائع يمكننا الاستفادة منه في مكوناتنا. غالبًا ما يكون من الأفضل إنشاء كل مكون ليكون عديمي الجنسية قدر الإمكان ، على افتراض أن الوالد سيرغب في التحكم في كل شيء منطقي. خذ مكون منسدلة بسيطة كمثال
class SimpleDropdown extends React . Component {
static propTypes = {
value : React . PropTypes . string ,
onChange : React . PropTypes . func ,
open : React . PropTypes . bool ,
onToggle : React . PropTypes . func ,
} ;
render ( ) {
return (
< div >
< input
value = { this . props . value }
onChange = { ( e ) => this . props . onChange ( e . target . value ) }
/ >
< button onClick = { ( e ) => this . props . onToggle ( ! this . props . open ) } >
open
< / button >
{ this . props . open && (
< ul className = "open" >
< li > option 1 < / li >
< li > option 2 < / li >
< / ul >
) }
< / div >
) ;
}
}
لاحظ كيف لا نتتبع أي حالة في منسدلة بسيطة؟ هذا أمر رائع لأن مستهلك الوحدة لدينا سيكون لديه كل المرونة لتحديد ما ينبغي أن يكون سلوك القائمة المنسدلة. لاحظ أيضًا أن واجهة برمجة التطبيقات (Proftypes) العامة ، تتكون من نمط مشترك: خاصية نريد تعيينها ( value
، open
) ، ومجموعة من المعالجات التي تشير إلى متى نريد تعيينها ( onChange
، onToggle
). الأمر متروك للمكون الأصل لتغيير value
open
الدعائم استجابة للمعالجات.
على الرغم من أن هذا النمط يوفر قدرًا ممتازًا من المرونة للمستهلكين ، إلا أنه يتطلب منهم أيضًا كتابة مجموعة من رمز Boilerplate الذي ربما لن يتغير كثيرًا من الاستخدام. في جميع الاحتمالات ، سوف يرغبون دائمًا في وضع open
استجابةً لـ onToggle
، وفقط في حالات نادرة لا يرغبون في تجاوز هذا السلوك. هذا هو المكان الذي يأتي فيه النمط الخاضع للرقابة/غير المنضبط.
نريد فقط التعامل مع حالة Open/Ontoggle بأنفسنا إذا لم يقدم المستهلك دعامة open
(تشير إلى أنهم يريدون التحكم فيه). بدلاً من تعقيد مكوننا المنسدلة مع كل هذا المنطق ، وإخفاء منطق العمل الخاص بنا ، يمكننا إضافته لاحقًا ، من خلال أخذ المنسدلة ولفنا داخل مكون آخر يتعامل معنا.
uncontrollable
يتيح لك فصل المنطق اللازم لإنشاء مدخلات محكومة/غير خاضعة للرقابة مما يتيح لك التركيز على إنشاء إدخال يتم التحكم فيه بالكامل ولفه لاحقًا. هذا يميل إلى أن يكون أكثر بساطة للعقل أيضًا.
import { uncontrollable } from 'uncontrollable' ;
const UncontrollableDropdown = uncontrollable ( SimpleDropdown , {
value : 'onChange' ,
open : 'onToggle'
} )
< UncontrollableDropdown
value = { this . state . val } // we can still control these props if we want
onChange = { val => this . setState ( { val } ) }
defaultOpen = { true } / > // or just let the UncontrollableDropdown handle it
// and we just set an initial value (or leave it out completely)!
الآن لا نحتاج إلى القلق بشأن Ontoggle المفتوح! سيتم تتبع المكون الذي تم إرجاعه open
لنا من خلال افتراض أنه يجب أن open
فقط على أي عودة onToggle
. إذا أردنا أن نقلق بشأن ذلك ، فيمكننا توفير الدعائم open
onToggle
وسيتم مرورها من خلالها.
ما سبق مثال مفتعلة ولكنه يتيح لك التفاف مكونات أكثر تعقيدًا ، مما يمنحك الكثير من المرونة في واجهة برمجة التطبيقات (API) يمكنك تقديم مستهلك للمكون. لكل زوج من زوجات الدعامة/المعالجات ، تحصل أيضًا على افتراضي من النموذج "الافتراضي [propname]" لذلك value
-> defaultValue
، و open
-> defaultOpen
، إلخ. هنا: https://github.com/jquense/reactwidgets/blob/5d1b530cb094cdc72f577fe01abe4a02dd265400/src/multiselect.jsx#l521