Hello, world!
React يجعل إنشاء واجهات المستخدم التفاعلية سهلا للغاية، ﻻ يجب عليك سوى أن تصمم واجهة بسيطة لكل حالة من حالات التطبيق و بعدها React يتكفل وبفاعلية بتحديث و إعادة رسم المكّون المعني بالتحديث فقط عند تغيُّر البيانات.
الواجهات المُعرّفة (التصريحية)، تجعل الشيفرة الخاصة بالبرنامج سهلة التوقع عند تنفيذها و سهلة التصحيح في حالة وجود أخطاء.
يعتمد React بشكل أساسي على مفهوم المكوّنات (Components). حيث يجب عليك بناء مكوّنات مُغلَّفة تُدير حالتها الخاصّة، ومن ثمّ تُركِّب هذه المكوّنات مع بعضها لإنشاء واجهات مستخدم مُعقّدة.
بما أنّ منطق المكوّنات مكتوب باستخدام JavaScript بدلًا من صيغة القوالب، فبإمكانك تمرير الكثير من البيانات عبر تطبيقك بسهولة وإبقاء الحالة بعيدة عن DOM.
نحن لا نضع أي فرضيات مسبقة عن التكنولوجيا الأخرى التي تستخدمها، فلهذا يمكنك تطوير ميزات و إضافات باستخدام React دون الحاجة الى إعادة كتابة أي شيفرة مكتوبة سابقاً.
يُمكِن تصيير React من جهة الخادم باستخدام Node.js، ويمكن إنشاء تطبيقات الهواتف الذكية عبر React Native.
كل مكوّن React مزوّد بالدّالة Render()
التي تأخذ البيانات المدخلة و تُرجع ما يجب اظهاره.
هذا المثال يستخدم تعابير تشبه XML أي (XML-Like) و التي تسمى JSX.
البيانات المرسلة خلال المكّون يمكن الوصول اليها ضمن الدالة Render()
بواسطة this.props
.
استخدام JSX اختياري، وليس مطلوباً او شرطاً لاستخدام React. جرّب Babel REPL لترى شيفرة الـ JavaScript الخام الموّلدة من خلال خطوة التحويل البرمجي لـ JSX.
class HelloMessage extends React.Component {
render() {
return
<div dir="rtl">مرحبا {this.props.name}</div>;
}
}
root.render(<HelloMessage name="أحمد" />);
بالإضافة الى أخذ بيانات الإدخال (التي يمكن الوصول إليها من خلال this.props
)، يستطيع المكوّن أن يحتفظ بحالة بياناته الداخلية (التي يمكن الوصول إليها من خلال this.state
) . عندما تتغير حالة بيانات المكوّن، العلامات المرسومة أو المُظهرة سيتم تحديثها و إعادة رسمها من خلال إعادة تنفيذ الدّالة render()
.
class Timer extends React.Component {
constructor(props) {
super(props);
this.state = { seconds: 0 };
}
tick() {
this.setState(state => ({
seconds: state.seconds + 1
}));
}
componentDidMount() {
this.interval = setInterval(() => this.tick(), 1000);
}
componentWillUnmount() {
clearInterval(this.interval);
}
render() {
return (
<div>
Seconds: {this.state.seconds}
</div>
);
}
}
root.render(<Timer />);
باستخدام props
و state
، نستطيع ان ننشأ برنامج صغير يعرض قائمة المهام التي يجب القيام بها (Todo list). هذا المثال يستخدم state
لمتابعة العناصر الموجودة في القائمة الحالية بالإضافة الى متابعة النص المُدخل من قبل المستخدم.
على الرغم من أن معالجات الأحداث تبدو وكأنها مُضمّنة، إلا أنه سيتم جمعها وتنفيذها باستخدام تفويض الحدث.
class TodoApp extends React.Component {
constructor(props) {
super(props);
this.state = { items: [], text: '' };
this.handleChange = this.handleChange.bind(this);
this.handleSubmit = this.handleSubmit.bind(this);
}
render() {
return (
<div>
<h3>TODO</h3>
<TodoList items={this.state.items} />
<form onSubmit={this.handleSubmit}>
<label htmlFor="new-todo">
What needs to be done?
</label>
<input
id="new-todo"
onChange={this.handleChange}
value={this.state.text}
/>
<button>
Add #{this.state.items.length + 1}
</button>
</form>
</div>
);
}
handleChange(e) {
this.setState({ text: e.target.value });
}
handleSubmit(e) {
e.preventDefault();
if (this.state.text.length === 0) {
return;
}
const newItem = {
text: this.state.text,
id: Date.now()
};
this.setState(state => ({
items: state.items.concat(newItem),
text: ''
}));
}
}
class TodoList extends React.Component {
render() {
return (
<ul>
{this.props.items.map(item => (
<li key={item.id}>{item.text}</li>
))}
</ul>
);
}
}
root.render(<TodoApp />);
يسمح React باستخدام مكتبات (Libraries) خارجية بالإضافة الى أُطر عمل (Frameworks).
هذا المثال يستخدم المكتبة remarkable كمكتبة خارجية لمعالجة تعابير من نوع Markdown، لتحويل قيمة <textarea>
بشكل آني.
class MarkdownEditor extends React.Component {
constructor(props) {
super(props);
this.md = new Remarkable();
this.handleChange = this.handleChange.bind(this);
this.state = { value: 'Hello, **world**!' };
}
handleChange(e) {
this.setState({ value: e.target.value });
}
getRawMarkup() {
return { __html: this.md.render(this.state.value) };
}
render() {
return (
<div className="MarkdownEditor">
<h3>Input</h3>
<label htmlFor="markdown-content">
Enter some markdown
</label>
<textarea
id="markdown-content"
onChange={this.handleChange}
defaultValue={this.state.value}
/>
<h3>Output</h3>
<div
className="content"
dangerouslySetInnerHTML={this.getRawMarkup()}
/>
</div>
);
}
}
root.render(<MarkdownEditor />);
Hello, world!