2024 أحدث أداة تعليميةReact هي مكتبة JavaScript لإنشاء واجهات المستخدم. إنه يمكّن المطورين من إنشاء مكونات واجهة المستخدم القابلة لإعادة الاستخدام وتحديث DOM بكفاءة باستخدام DOM الظاهري للأداء الأمثل.
إذا كنت ترغب في إنشاء تطبيق أو موقع ويب جديد تمامًا مع React ، أقترح اختيار أحد الأطر التي تعمل بسلطة React التي تحظى بشعبية في المجتمع.
يمكنك استخدام React بدون إطار عمل ، لكننا وجدنا أن معظم التطبيقات والمواقع تحتاج في النهاية إلى معالجة المشكلات الشائعة مثل تقسيم التعليمات البرمجية والتوجيه وجلب البيانات وتوليد HTML. هذه التحديات ليست فريدة من نوعها للرد ولكنها شائعة في جميع مكتبات واجهة المستخدم.
من خلال البدء بإطار عمل ، يمكنك الاستيلاء بسرعة مع React وتجنب الحاجة إلى تطوير إطارك الخاص لاحقًا.
Next.js 'Pages Router هو إطار رد فعل كامل المكاسب. إنه متعدد الاستخدامات ويتيح لك إنشاء تطبيقات React من أي حجم - من المدونة الثابتة في الغالب إلى تطبيق ديناميكي معقد. لإنشاء مشروع NEXT.JS جديد ، قم بتشغيله في محطةك:
npx create-next-app@latest
يتم الحفاظ على Next.js بواسطة Vercel. يمكنك نشر تطبيق next.js على أي node.js أو استضافة بدون خادم ، أو على الخادم الخاص بك. يدعم Next.js أيضًا تصدير ثابت لا يتطلب خادمًا.
O App Router Do Next.js هو إعادة تصميم لبرنامج APIs Next.js تهدف إلى تحقيق رؤية الهندسة المعمارية الكاملة لفريق React. يتيح لك جلب البيانات في مكونات غير متزامنة تعمل على الخادم أو حتى أثناء الإنشاء.
يتم الحفاظ على Next.js بواسطة Vercel. يمكنك نشر تطبيق next.js على أي node.js أو استضافة بدون خادم ، أو على الخادم الخاص بك. Next.js يدعم أيضًا التصدير الثابت الذي لا يتطلب خادمًا.
نظرة عامة على Vite (الكلمة الفرنسية لـ "Quick" ، واضحة /VIT /، مثل "VEET") هي أداة بناء تهدف إلى توفير تجربة تطوير أسرع وأكقل لمشاريع الويب الحديثة. يتكون من جزأين رئيسيين:
خادم DEV يوفر تحسينات للميزات الغنية على وحدات ES الأصلية ، على سبيل المثال استبدال الوحدة النمطية السريعة للغاية (HMR).
يقوم أمر بناء يحدد الكود الخاص بك مع Rollup ، تم تكوينه مسبقًا لإخراج الأصول الثابتة المحسّنة للغاية للإنتاج.
تم رأي Vite ويأتي مع الافتراضات المعقولة خارج الصندوق. اقرأ عن ما هو ممكن في دليل الميزات. من الممكن دعم الأطر أو التكامل مع الأدوات الأخرى من خلال الإضافات. يشرح قسم التكوين كيفية تكييف Vite مع مشروعك إذا لزم الأمر.
قبل البدء ، تأكد من تثبيت Node.js على نظامك. إذا لم يكن لديك ذلك بعد ، فيمكنك تنزيله من موقع Node.js الرسمي ، فهذا أمر بسيط حقًا.
npx create-vite your-project-name --template react
استبدل اسم المشروع الخاص بك بالاسم الذي تريده لمشروعك. يدعم Vite العديد من الأطر ، ولكن في هذه الحالة ، نحدد قالب React مع خيار React -template.
cd your-project-name
لا تنس أن تحل محل اسم المشروع الخاص بك بالاسم الفعلي الذي اخترته لمشروعك (ما لم تكن بالطبع تريد الاحتفاظ بهذا الاسم لمشروعك).
npm
npm run dev
بعد تشغيل هذه الأوامر ، يجب أن ترى رسالة في المحطة الخاصة بك تشير إلى أن موقع الويب الخاص بك REACT يعمل على منفذ معين ، وعادة ما يكون رقم منفذ "عشوائي" مثل http: // localhost: 5173. الآن ، افتح متصفحك وقم بزيارة عنوان URL المقدم لرؤية موقع الويب الخاص بك في العمل.
استخدم أدوات React Developer لفحص مكونات React ، وتحرير الدعائم والحالة ، وتحديد مشاكل الأداء.
امتداد المتصفح إن أسهل طريقة لتصحيح مواقع الويب التي تم إنشاؤها مع React هي تثبيت امتداد متصفح أدوات Developer Tools. وهي متوفرة للعديد من المتصفحات الشعبية:
بالنسبة للمتصفحات الأخرى (على سبيل المثال ، Safari) ، قم بتثبيت حزمة NPM Deptols:
# Yarn
yarn global add react-devtools
# Npm
npm install -g react-devtools
فتح أدوات المطور التالية من المحطة:
react-devtools
ثم قم بتوصيل موقع الويب الخاص بك عن طريق إضافة علامة <script> التالية إلى بداية موقع الويب الخاص بك:
<html>
<head>
<script src="http://localhost:8097"></script>
JSX هو امتداد بناء الجملة لـ JavaScript يشبه XML أو HTML. يسمح للمطورين بكتابة عناصر ومكونات HTML بطريقة أكثر إيجازًا وقابلة للقراءة داخل ملفات JavaScript.
import React from 'react';
function App() {
return (
<div>
<h1>Hello, React!</h1>
</div>
);
}
export default App;
المكونات الوظيفية هي وظائف بسيطة تقبل الدعائم كوسيطة وإرجاع عناصر JSX. مع خطافات رد الفعل ، يمكن أن يكون للمكونات الوظيفية أيضًا آثارًا جانبية وجانبية.
import React from 'react';
const FunctionalComponent = () => {
return <p>This is a functional component.</p>;
}
export default FunctionalComponent;
مكونات الفصل هي فئات ES6 التي تمتد مكون React. يمكنهم الحفاظ على الدولة المحلية وإدارتها والوصول إلى أساليب دورة الحياة ، مما يجعلها أكثر غنية بالميزات من المكونات الوظيفية.
import React, { Component } from 'react';
class ClassComponent extends Component {
render() {
return <p>This is a class component.</p>;
}
}
export default ClassComponent;
الدعائم هي وسيلة لتمرير البيانات من مكون الأصل إلى مكون الطفل في React. أنها غير قابلة للتغيير وتوفر وسيلة لجعل المكونات ديناميكية وقابلة لإعادة الاستخدام.
import React from 'react';
const PropsExample = (props) => {
return <p>{props.message}</p>;
}
export default PropsExample;
يمثل رد فعل الحالة الحالة المتغيرة للمكون. يتيح هذا المكونات إدارة بياناتها وتحديثها ، مما يؤدي إلى واجهات المستخدم الديناميكية والتفاعلية.
import React, { Component } from 'react';
class StateExample extends Component {
constructor(props) {
super(props);
this.state = {
count: 0
};
}
render() {
return (
<div>
<p>Count: {this.state.count}</p>
<button onClick={() => this.setState({ count: this.state.count + 1 })}>
Increment
</button>
</div>
);
}
}
export default StateExample;
أساليب دورة الحياة São métodos especiais em components de classe que são invocados em diferentes fates do ciclo de vida de um componente. ComponentDidmount é um método de ciclo de vida comummente utilizado ، executado depois de um componente ser renderizado no dom.
import React, { Component } from 'react';
class LifecycleExample extends Component {
componentDidMount() {
console.log('Component is mounted!');
}
render() {
return <p>Lifecycle Example</p>;
}
}
export default LifecycleExample;
يستخدم React Camelcase للتعامل مع الأحداث. يمكن تعريف الوظائف للتعامل مع الأحداث مثل النقرات والتغييرات ، وما إلى ذلك ، وتوفير التفاعل للمكونات.
import React from 'react';
const EventHandlingExample = () => {
const handleClick = () => {
alert('Button clicked!');
}
return (
<button onClick={handleClick}>
Click me
</button>
);
}
export default EventHandlingExample;
السنانير رد الفعل هي وظائف تسمح للمكونات الوظيفية بإدارة الآثار الجانبية للدولة والجانبية. تم تقديمها في React 16.8 وتقديم طريقة أكثر إيجازًا للعمل مع أساليب الدولة ودورة الحياة في المكونات الوظيفية.
import React, { useState } from 'react';
const UseStateExample = () => {
const [count, setCount] = useState(0);
return (
<div>
<p>Count: {count}</p>
<button onClick={() => setCount(count + 1)}>
Increment
</button>
</div>
);
}
export default UseStateExample;
المكونات التي يتم التحكم فيها في React لها مدخلات وحالتها تسيطر عليها React. يتلقون قيمتها الحالية ومعالج onchange كدعائم ، مما يجعلها تتحكم في رد الفعل وليس من قبل DOM.
import React, { useState } from 'react';
const ControlledComponent = () => {
const [inputValue, setInputValue] = useState('');
const handleChange = (e) => {
setInputValue(e.target.value);
}
return (
<input
type="text"
value={inputValue}
onChange={handleChange}
placeholder="Type here"
/>
);
}
export default ControlledComponent;
حدود الخطأ هي مكونات رد الفعل التي تكتشف أخطاء JavaScript في أي مكان في شجرة مكون الطفل وتسجيل تلك الأخطاء ، وتقدم واجهة مستخدم احتياطي أو اتخاذ إجراءات أخرى.
import React, { Component } from 'react';
class ErrorBoundary extends Component {
constructor(props) {
super(props);
this.state = { hasError: false };
}
static getDerivedStateFromError(error) {
return { hasError: true };
}
componentDidCatch(error, errorInfo) {
logErrorToMyService(error, errorInfo);
}
render() {
if (this.state.hasError) {
return <p>Something went wrong.</p>;
}
return this.props.children;
}
}
export default ErrorBoundary;
مكونات الترتيب الأعلى (HOCs) هي وظائف تأخذ مكونًا وإرجاع مكون جديد مع وظائف إضافية. إنها وسيلة لإعادة استخدام منطق المكون.
import React from 'react';
const WithLogger = (WrappedComponent) => {
return class extends React.Component {
componentDidMount() {
console.log('Component is mounted!');
}
render() {
return <WrappedComponent {...this.props} />;
}
};
}
export default WithLogger;
// Usage
import React from 'react';
import WithLogger from './WithLogger';
const MyComponent = () => {
return <p>My Component</p>;
}
const EnhancedComponent = WithLogger(MyComponent);
يوفر React وظيفة map لتقديم قوائم العناصر ديناميكيًا. يتم تعيين كل عنصر في الصفيف إلى عنصر React ، مما يسهل تقديم محتوى ديناميكي.
import React from 'react';
const RenderingList = () => {
const items = ['Item 1', 'Item 2', 'Item 3'];
return (
<ul>
{items.map((item, index) => (
<li key={index}>{item}</li>
))}
</ul>
);
}
export default RenderingList;
يوفر API Context API في React طريقة لنقل البيانات عبر شجرة المكون دون الحاجة إلى تمرير الدعائم يدويًا في كل مستوى. إنه مفيد لمشاركة القيم مثل السمات أو حالة المصادقة.
import React from 'react';
const ThemeContext = React.createContext('light');
export default ThemeContext;
import React, { useContext } from 'react';
import ThemeContext from './ThemeContext';
const ThemedComponent = () => {
const theme = useContext(ThemeContext);
return <p style={{ color: theme === 'light' ? 'black' : 'white' }}>Themed Component</p>;
}
export default ThemedComponent;
تساعد المفاتيح في رد الفعل على تحديد العناصر التي تم تغييرها أو إضافتها أو إزالتها. يجب أن تكون فريدة من نوعها في القائمة والمساعدة في الرد مع التحديثات الفعالة.
import React from 'react';
const KeysExample = () => {
const data = [
{ id: 1, name: 'Item 1' },
{ id: 2, name: 'Item 2' },
{ id: 3, name: 'Item 3' },
];
return (
<ul>
{data.map(item => (
<li key={item.id}>{item.name}</li>
))}
</ul>
);
}
export default KeysExample;
يتضمن المعالجة في React إدارة بيانات النماذج باستخدام الحالة والتعامل مع تقديم النموذج عبر معالجات الأحداث. يتم استخدام المكونات التي يتم التحكم فيها لمزامنة عناصر النماذج مع حالة React.
import React, { useState } from 'react';
const FormExample = () => {
const [formData, setFormData] = useState({ username: '', password: '' });
const handleChange = (e) => {
setFormData({
...formData,
[e.target.name]: e.target.value,
});
}
const handleSubmit = (e) => {
e.preventDefault();
console.log('Form submitted:', formData);
}
return (
<form onSubmit={handleSubmit}>
<label>
Username:
<input
type="text"
name="username"
value={formData.username}
onChange={handleChange}
/>
</label>
<label>
Password:
<input
type="password"
name="password"
value={formData.password}
onChange={handleChange}
/>
</label>
<button type="submit">Submit</button>
</form>
);
}
export default FormExample;
أنماط مضمّنة: يتيح لك React تصميم مكونات باستخدام أنماط مضمّنة ، حيث يتم تعريف الأنماط على أنها كائنات وتطبيقها مباشرة على العناصر.
import React from 'react';
const InlineStyleExample = () => {
const styles = {
color: 'blue',
fontSize: '18px',
};
return <p style={styles}>Styled with inline styles</p>;
}
export default InlineStyleExample;
Render Props هي تقنية لمشاركة التعليمات البرمجية بين مكونات React باستخدام دعامة قيمتها هي وظيفة. هذا يسمح للتكوين الديناميكي للمكونات.
import React, { useState } from 'react';
const MouseTracker = ({ render }) => {
const [position, setPosition] = useState({ x: 0, y: 0 });
const handleMouseMove = (event) => {
setPosition({ x: event.clientX, y: event.clientY });
}
return (
<div style={{ height: '100vh' }} onMouseMove={handleMouseMove}>
{render(position)}
</div>
);
}
export default MouseTracker;
// Usage
import React from 'react';
import MouseTracker from './MouseTracker';
const App = () => {
return (
<MouseTracker
render={(position) => (
<p>
Mouse position: {position.x}, {position.y}
</p>
)}
/>
);
}
export default App;
تساعد وحدات CSS في تحديد نطاق الأنماط لمكون معين ، وتجنب تعارضات على النمط العالمي. يمكن أن يكون لكل مكون وحدة CSS الخاصة به مع أنماط تم تحديدها محليًا.
.myComponent {
color: green;
}
import React from 'react';
import styles from './CSSModulesExample.module.css';
const CSSModulesExample = () => {
return <p className={styles.myComponent}>Styled with CSS Modules</p>;
}
export default CSSModulesExample;
سمات:
import React, { useState } from 'react';
const TodoApp = () => {
const [tasks, setTasks] = useState([]);
const [newTask, setNewTask] = useState('');
const addTask = () => {
setTasks([...tasks, { text: newTask, completed: false }]);
setNewTask('');
};
const toggleTask = (index) => {
const updatedTasks = [...tasks];
updatedTasks[index].completed = !updatedTasks[index].completed;
setTasks(updatedTasks);
};
const removeTask = (index) => {
const updatedTasks = [...tasks];
updatedTasks.splice(index, 1);
setTasks(updatedTasks);
};
return (
<div>
<input
type="text"
value={newTask}
onChange={(e) => setNewTask(e.target.value)}
/>
<button onClick={addTask}>Add Task</button>
<ul>
{tasks.map((task, index) => (
<li key={index}>
<input
type="checkbox"
checked={task.completed}
onChange={() => toggleTask(index)}
/>
<span style={{ textDecoration: task.completed ? 'line-through' : 'none' }}>
{task.text}
</span>
<button onClick={() => removeTask(index)}>Remove</button>
</li>
))}
</ul>
</div>
);
};
export default TodoApp;
يوضح مثال تطبيق الطقس هذا التطبيق العملي لمفاهيم React ، بما في ذلك إدارة الدولة ، والاستخدام للآثار الجانبية ، ومعالجة الأحداث ، وتفاعل API وتقديم مشروط. يمكن للمستخدمين تعلم كيفية إنشاء تطبيق للطقس الوظيفي وفهم تكامل السنانير React في سيناريوهات العالم الحقيقي.
الفيضان:
مكون وظيفي وسنانير الحالة:
useState weather city .استخدام useFefect للحصول على البيانات:
يتم استخدام خطافات useEffect لإجراء الآثار الجانبية ، مثل جلب بيانات الطقس من API OpenWeathermap.
وظيفة fetchWeatherData غير متزامنة وتتجلب بيانات الطقس استنادًا إلى المدينة المحددة باستخدام API fetch .
التقديم الشرطي:
يتم تقديم بيانات الطقس بشكل مشروط فقط إذا كانت موجودة ( weather && ... ).
معالجة الأحداث:
setCity في حدث onChange .تفاعل API:
محتوى تحديث ديناميكي:
التصميم:
تحويل درجة الحرارة:
// src/RealWorldExamples/WeatherApp.js
import React, { useState, useEffect } from 'react';
const WeatherApp = () => {
const [weather, setWeather] = useState(null);
const [city, setCity] = useState('New York');
const apiKey = 'YOUR_OPENWEATHERMAP_API_KEY';
useEffect(() => {
// Fetch weather data from OpenWeatherMap API
const fetchWeatherData = async () => {
try {
const response = await fetch(
`https://api.openweathermap.org/data/2.5/weather?q=${city}&appid=${apiKey}`
);
if (!response.ok) {
throw new Error('Failed to fetch weather data');
}
const data = await response.json();
setWeather(data);
} catch (error) {
console.error(error.message);
}
};
fetchWeatherData();
}, [city, apiKey]);
return (
<div>
<h1>Weather App</h1>
<label>
Enter City:
<input
type="text"
value={city}
onChange={(e) => setCity(e.target.value)}
/>
</label>
{weather && (
<div>
<h2>{weather.name}, {weather.sys.country}</h2>
<p>Temperature: {Math.round(weather.main.temp - 273.15)}°C</p>
<p>Weather: {weather.weather[0].description}</p>
</div>
)}
</div>
);
};
export default WeatherApp;
أفضل الممارسات:
/src
/components
/Button
Button.js
Button.test.js
Button.css
/features
/Todo
TodoList.js
TodoItem.js
TodoForm.js
/styles
global.css
/tests
/unit
Button.test.js
/integration
TodoIntegration.test.js
أفضل الممارسات:
// Using React.memo
const MemoizedComponent = React.memo(({ data }) => {
// Component logic
});
// Using Code Splitting and Lazy Loading
const MyComponent = React.lazy(() => import('./MyComponent'));
// In your component
const App = () => (
<React.Suspense fallback={<LoadingSpinner />}>
<MyComponent />
</React.Suspense>
);
أفضل الممارسات:
مثال:
// Jest Unit Test
test('renders correctly', () => {
const { getByText } = render(<Button label="Click me" />);
expect(getByText('Click me')).toBeInTheDocument();
});
// Jest Integration Test
test('increments count on button click', () => {
const { getByText } = render(<Counter />);
fireEvent.click(getByText('Increment'));
expect(getByText('Count: 1')).toBeInTheDocument();
});
// React Testing Library
import { render, screen } from '@testing-library/react';
import userEvent from '@testing-library/user-event';
test('clicking button increments count', () => {
render(<MyComponent />);
userEvent.click(screen.getByRole('button'));
expect(screen.getByText('Count: 1')).toBeInTheDocument();
});
أفضل الممارسات:
استخدم جهاز توجيه React للتوجيه من جانب العميل في تطبيق من صفحة واحدة.
تحديد الطرق إلى طرق عرض أو أقسام مختلفة من التطبيق الخاص بك.
قم بتنفيذ مكونات التنقل ، مثل <Link> ، للسماح بسهولة التنقل بين الطرق.
مثال:
// React Router
import { BrowserRouter as Router, Route, Link } from 'react-router-dom';
const App = () => (
<Router>
<nav>
<ul>
<li><Link to="/">Home</Link></li>
<li><Link to="/about">About</Link></li>
<li><Link to="/contact">Contact</Link></li>
</ul>
</nav>
<Route path="/" exact component={Home} />
<Route path="/about" component={About} />
<Route path="/contact" component={Contact} />
</Router>
);
أفضل الممارسات:
// Using Local Component State
const Counter = () => {
const [count, setCount] = useState(0);
return (
<div>
<p>Count: {count}</p>
<button onClick={() => setCount(count + 1)}>Increment</button>
</div>
);
};
// Using Context API
const ThemeContext = React.createContext('light');
const ThemedComponent = () => {
const theme = useContext(ThemeContext);
return <p style={{ color: theme === 'light' ? 'black' : 'white' }}>Themed Component</p>;
};
// Using Redux
// (Assuming you have a Redux store configured)
import { useSelector, useDispatch } from 'react-redux';
const CounterRedux = () => {
const count = useSelector(state => state.count);
const dispatch = useDispatch();
return (
<div>
<p>Count: {count}</p>
<button onClick={() => dispatch({ type: 'INCREMENT' })}>Increment</button>
</div>
);
};
أفضل الممارسات:
مثال:
أفضل الممارسات:
مثال:
// Error Boundary
class ErrorBoundary extends React.Component {
constructor(props) {
super(props);
this.state = { hasError: false };
}
static getDerivedStateFromError(error) {
return { hasError: true };
}
componentDidCatch(error, errorInfo) {
logErrorToService(error, errorInfo);
}
render() {
if (this.state.hasError) {
return <p>Something went wrong. Please try again.</p>;
}
return this.props.children;
}
}
أفضل الممارسات:
مثال:
// Semantic HTML Elements
<article>
<h2>Article Title</h2>
<p>Article content...</p>
</article>
// ARIA Roles and Attributes
<button aria-label="Close" onClick={handleClose}>
✕
</button>
// Keyboard Navigation
<input type="text" onKeyDown={handleKeyDown} />
أفضل الممارسات:
مثال:
// Using React.memo
const MemoizedComponent = React.memo(({ data }) => {
// Component logic
});
// Using Code Splitting and Lazy Loading
const MyComponent = React.lazy(() => import('./MyComponent'));
// In your component
const App = () => (
<React.Suspense fallback={<LoadingSpinner />}>
<MyComponent />
</React.Suspense>
);
// Using PureComponent
class PureCounter extends React.PureComponent {
render() {
return <p>Count: {this.props.count}</p>;
}
تحديث التبعيات بانتظام للاستفادة من الميزات الجديدة وإصلاحات الأخطاء وتصحيحات الأمان.
اتبع الإصدار الدلالي للمكتبات والحزم المستخدمة في المشروع.
كن حذرًا مع التحديثات الرئيسية واختبارها جيدًا قبل التحديث.
مثال:
# Regularly update dependencies
npm update
# Follow semantic versioning
# Example: Major.Minor.Patch
# ^1.2.3 means any version that is compatible with 1.2.3
تكوين WebPack لبناء الإنتاج مع التحسينات:
// webpack.config.js
const path = require('path');
module.exports = {
mode: 'production',
entry: './src/index.js',
output: {
filename: 'bundle.js',
path: path.resolve(__dirname, 'dist'),
},
// Other webpack configurations...
};
شكرًا لك على اهتمامك بالمساهمة في هذا البرنامج التعليمي المذهل! تساعد مساهماتك في جعل هذا المورد أكثر قيمة للطلاب من جميع المستويات. سواء كنت تقوم بإصلاح خطأ أو تحسين ميزة موجودة أو إضافة شيء جديد تمامًا ، فإن جهودك تحدث فرقًا.
** شوكة المستودع: انقر فوق الزر "شوكة" في الزاوية اليمنى العليا من هذا المستودع لإنشاء نسختك.
** استنساخ المستودع: استنساخ المستودع إلى جهازك المحلي باستخدام git clone https://github.com/DaveSimoes/React-Tutorial-2024.git
** قم بإنشاء فرع: قم بإنشاء فرع جديد لمساهمتك مع اسم وصفي: git checkout -b your-feature .
** قم بإجراء تغييرات: قم بإجراء تغييراتك في الملفات المناسبة. لا تتردد في تحسين الأمثلة الحالية ، أو إضافة أحدث ، أو الأخطاء المطبعية أو تحسين الوثائق.
** ارتكاب تغييرات: أرسل التغييرات الخاصة بك برسالة واضحة وموجزة: git commit -m "Your message here" .
** قم بتغييرات الدفع: أرسل التغييرات الخاصة بك إلى مستودع متشعب: git push origin your-feature .
إنشاء طلب سحب: افتح طلب سحب في المستودع الأصلي. fornça um título Claro ، descreva suas alterações e envie o request.
اتبع أنماط الترميز المتسقة. تأكد من توثيق الرمز الخاص بك بشكل جيد ، خاصة إذا كنت تضيف أمثلة أو ميزات جديدة.
شكرا لك على النظر في المساهمة في هذا البرنامج التعليمي React. إن تفانيك في جعل هذا المورد أفضل موضع تقدير كبير. دعونا نتعلم وننمو معًا!
إذا وجدت هذا البرنامج التعليمي React مفيد ، فكر في إعطائه نجمة! دعمك محفز بشكل لا يصدق ويساعد الآخرين على اكتشاف هذا المورد. شكرا لكونك جزء من مجتمعنا و HAP!
رد فعل المكتبة الرسمية