كتابة ثابتة في تطبيق React

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

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

لذلك ، اليوم سوف نلقي نظرة على الاحتمالات التي يوفرها دمج أداتين رائعتين: TypeScript و React.



أمثلة


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

import * as React from 'react'; const HelloWorld: React.FunctionComponent<{ name: string; }> = ({ name = 'World' }) => { return <div>Hello, {props.name}</div>; }; export default HelloWorld; 

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

كل هذا لا يبدو معقدا. ماذا عن مكونات الفصل؟

 import * as React from 'react'; interface State { name: string; } interface Props {} class HelloWorld extends React.Component<Props, State> { state = { name: 'World' } setName(name: string) { this.setState({ name }); } redner() { return ( <React.Fragment> <hI>Hello, {this.state.name}</hI> <input value={this.state.name} onChange={(e) => this.setName(e.target.value)} /> </React.Fragment> ); } } 

في مثال الفصل ، أنشأنا واجهات اثنين: الدعائم والدولة. بمساعدتهم ، حددنا تواقيع الدعائم الواردة (فارغة) وتوقيع حالة المكون - كما في المثال مع المكونات الوظيفية.

يمكننا أيضا إضافة القيم الدعائم الافتراضية.

 import * as React from 'react'; interface Props { name?: string; } export default class HelloWorld extends React.Component<Props> { static defaultProps: Props = { name: 'World' }; render () { return <hI>Hello, {this.props.name}</hI>; } } 

هذا كل شئ! تطبيق React الصغير الخاص بنا مكتوب بالفعل بقوة على مستوى المعلمات وقيم حالة المكون.

دعونا نلقي نظرة على المزايا التي أعطانا هذا:

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


التعداد في المعلمات



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

  import * as React from 'react'; enum Colors { RED, BLUE, GREEN } const ColorResult: React.FunctionComponent<{ color: Colors; }> = ({ color = Colors.Red }) => { return <div>Your color is {props.color}</div>; }; export default ColorResult; 

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

استرجاع صارم


في عام 2019 ، لا يزال لدينا العديد من التطبيقات التي تعمل على Redux. يمكن لـ TypeScript المساعدة في هذا الموقف.

 import * as React from 'react'; const initialState = { name: 'World' }; type HelloWorldStateProps = Readonly<typeof initialState>; interface Action { type: string; name?: string; } const worldNameReducer = ( state: HelloWorldStateProps = initialState, action: Action ): HelloWorldStateProps => { switch (action.type) { case "SET": return { name: action.name }; case "CLEAR": return { name: initialState.name }; default: return state; } }; const set = (name): Action => ({ type: "SET", name }); const clear = (): Action => ({ type: "CLEAR" }); const store = createStore( combineReducers({ world: worldNameReducer }) ); type StateProps = ReturnType<typeof mapStateToProps>; type DispatchProps = typeof mapDispatchToProps; interface AppProps extends StateProps, DispatchProps {} interface AppState extends StateProps {} class App extends React.Component<AppProps, AppState> { state = { name: initialState.name } setName(name: string) { this.setState({ name }); } render() { const { set, clear, name } = this.props; return ( <div> <hI>Hello, {name}</hI> <input value={this.state.name} onChange={(e) => this.setName(e.target.value)} /> <button onClick={() => set(this.state.name)}>Save Name</button> <button onClick={() => clear()}>Clear</button> </div> ); } } const mapStateToProps = ({ world }: { world: HelloWorldStateProps }) => ({ name: world.name, }); const mapDispatchToProps = { set, clear }; const AppContainer = connect( mapStateToProps, mapDispatchToProps )(App); render( <Provider store={store}> <AppContainer /> </Provider>, document.getElementById("root") ); 

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

المستوى التالي من الكتابة هو المكون. هنا قمنا بتطبيق وراثة النوع على AppProps و AppState. لماذا تكتب أكثر عندما يكون لدينا بالفعل أنواع بيانات بها مثل هذه التوقيعات؟ من الأسهل الحفاظ على النظام. إذا قمت بتغيير بعض العناصر ، فستحدث تغييرات لجميع الورثة.

استنتاج


TypeScript هي لغة مفيدة للغاية تعمل على رأس JavaScript. بالتزامن مع React ، فإنه يوفر ممارسات برمجة رائعة حقًا لتطبيقات Frontend.

Source: https://habr.com/ru/post/ar465461/


All Articles