اذهب إلى المحتوى

Mohammed Saber6

الأعضاء
  • المساهمات

    1036
  • تاريخ الانضمام

  • تاريخ آخر زيارة

  • عدد الأيام التي تصدر بها

    10

كل منشورات العضو Mohammed Saber6

  1. هذا يسمى بال decorator وتستطيع التعرف عليه مباشرة إذا كان متبوعاً بعلامة ال @ وهي عبارة عن إحاطة جزء من الكود بجزء آخر مثل ال HOCS وفي حالتك أنت تريد أن تحيط المكون الخاص بك App بال Store ولذلك كتبت هكذا @connect(mapStateToProps, mapDispatchToProps) // هذا يحيط ما يليه export default class App extends React.Component { // هذا لديه بيانات من ال store .... }
  2. نقوم بعمل دالة تقوم بتعديل قيمة الحقل في ال state هذا هو المثال بالشرح import * as React from 'react'; import { Button, Text, TextInput, View } from 'react-native'; export default class InsuranceInformation extends React.Component { constructor(props) { super(props); this.state = { inputs: [ // أولاً نضيف معرفات لكل حقل لكي نستهدف الحقل به وفي حالتنا سيكون id { id: 1, type: 'text', label: 'الأسم الأول', value: '' }, { id: 2, type: 'text', label: 'الأسم الثاني', value: '' }, { id: 3, type: 'date', label: 'تاريخ الميلاد', value: '' }, { id: 4, type: 'text', label: 'العنوان (1)', value: '' }, { id: 5, type: 'text', label: 'العنوان (2)', value: '' }, { id: 6, type: 'number', label: 'رقم الجوال', value: '' }, { id: 7, type: 'text', label: 'رقم البطاقة', value: '' }, { id: 8, type: 'number', label: 'رقم التأمين السابق', value: '' } ] }; this.handleSubmit = this.handleSubmit.bind(this); } updateFieldValue = (id, value) => { // نقوم بالبحث عن الحقل الذي نكتب فيه ونعدل قيمته const modifiedInputs = this.state.inputs.map(input => { if(input.id === id) { input.value = value; } return input; }) // ثم نعطي الحقول بالتعديلات الجديدة لل state this.setState({ inputs: modifiedInputs }) } handleSubmit(e) {} render() { const { title } = this.props; return ( <View> <Text>{title}</Text> { this.state.inputs.map(input => ( <TextInput value={input.value} // نقوم بعمل دالة تقوم بتعديل قيمة الحقل في ال state onChangeText={text => this.updateFieldValue(input.id, text)} placeholder={input.label} /> )) } <Button onPress={this.handleSubmit} title="إرسال" /> </View> ); } }
  3. لديك عدة طرق يمكنك أ ن تحفظ الحالة كلها في ال local storage هكذا import { createStore } from 'redux'; import rootReducer from './rootReducer'; const store = createStore(rootReducer); localStorage.setItem('appState', JSON.stringify(store)) export default store; ثم عند استخدامها عند بدء ال application مثلاً باستدعائها واستخدامها const state = JSON.parse(localStorage.getItem('appState')) || {} أن تستخدم مكتبة جاهزة توفر عليك مثل مكتبة redux-persist
  4. هذا طبيعي فهذا ما يسمى بال event ولأن ال li عنصر داخلي لل ul فلذلك عند الضغط عليه سيمرر حدث ليقوم الأب بتنفيذ ال onClick الخاصة به ولكن إذا لم تكن تريد هذا وتريد منع وصول ال event من الطفل إلى الأب فقط قم بما يلي لعناصر ال li <li onClick={(e) => { e.stopPropagation(); // هذا السطر سيمنع مرور الحدث من الطفل إلى الأب console.log('child1'); }} > list1 </li>
  5. هذه طريقة جيدة بالفعل ولكن في حالة لم يكن لديك أكثر من تنسيق أو اثنين لكن لو زاد عن هذا تقوم بعمل دالة كالآتي: import React from 'react'; class App extends React.Component() { wrapperStyles = status => { const completed = status === 'completed'; return { color: completed ? 'green' : 'none', backgroundColor: completed ? 'red' : 'aqua', } }; render() { return ( <div style={this.wrapperStyles()}></div> ); } } export default App;
  6. يجب عليك وضع كل ماهو خاص في ملف .env بجانب ال src وتكون لديك نسخة محلية منه وتتجاهل رفعها أثناء ال build ويكون لديك ملف مشابه مرفوع علي السيرفر بحيث تشير إليه عندما تريد استخدام المتغيرات الخاصة التي وضعتها project | |____ src |____ .env وبداخل ملف ال env تستخدم متغيرات خاصة تبدأ ب REACT_APP ثم الإسم الذي تريده هكذا REACT_APP_TOKEN="111111111111" REACT_APP_SECRET="Any thing" طبعاً عند استخدامها في الكود البرمجي الخاص بك تستخدم الآتي: process.env.REACT_APP_TOKEN process.env.REACT_APP_SECRET وهذا مرجع لك للتعمق أكثر
  7. الخطأ لديك هو في استدعاء الصور المحلية لديك طريقتين لحل المشكلة استخدام require this.state = { images: [ { source: require('./src/photos/01.jpg') }, { source: require('./src/photos/02.jpg') } ] }; أو استخدام uri class DynamicImageComponent extends React.Component { render() { return ( <Image source={{ uri: this.props.source }} /> ); } };
  8. هذا بسبب <React.StrictMode> وهو يقوم بعمل render مرتين فقط في البيئة التطويرية وليس بيئة ال production ويفعل هذا لكي يكتشف الأخطاء ويعمل تحذير بهم وهذا مفيد . إذا لا تريد هذا فقط قم بحذف <React.StrictMode>
  9. هذا النمط يؤذي ال performance لأن الدالة سيتم إنشاؤها في كل مرة مع كل render وبالتالي في حالتك سيتم إنشاء المكون IconButton - Checkbox - img دائماً مع كل render ولحل هذه المشكلة فقط قم بالإشارة إليها هكذا selectPerson = tile => { // قم بعمل ما تريد } handleDelete = tile => { // قم بعمل ما تريد } handleOpen = img => { // قم بعمل ما تريد } {this.state.people.map(tile => ( <span key={tile.img}> <Checkbox onCheck={this.selectPerson(tile)} /> <GridTile actionIcon={<IconButton onClick={this.handleDelete(tile)}><Delete color="red"/></IconButton>}> <img onClick={this.handleOpen(tile.img)} src={tile.img} /> </GridTile> </span> ))}
  10. عندما تستخدم الطريقة الأولى سيتم إزالة جميع النتائج الموجودة في ال state وسيتم وضع النتائج الجديدة دائماً. أما إذا كنت تريد الحفاظ على النتائج القديمة مثلاً تستخدم الطريقة الثانية حتى لا تمسح القديم
  11. يمكنك عملها بالجافاسكربت مباشرة حيث تقوم بعمل utility واستخدامها في أي مكان عن طريق استخدام URLSearchParams والذي يتعامل مع ال query params هكذا const queryParser = new URLSearchParams(window.location.search); وعندما تريد استخراج key معين تقوم بعمل الآتي: const firbaseKey = queryParser.get('__firebase_request_key');
  12. يمكنك استخدام data-wow-offset لتحديد المسافة من أسفل التي سيبدأ منها ال animation <section class="wow slideInRight" data-wow-offset="10" data-wow-iteration="10"></section> أو من الإعدادات wow = new WOW( { boxClass: 'wow', // default animateClass: 'animated', // default offset: 0, // هنا تقوم بعمل التغيير mobile: true, // default live: true // default } ) wow.init();
  13. إذا كنت تريد تغيير الحالة عند بدء الصفحة بعد ٣ ثواني يمكنك عملها في ال componentDidMount وليس ال render أي عند البدء import * as React from 'react'; import { Text, View, StyleSheet } from 'react-native'; function Feed() { return <Text>مرحباً</Text>; } function Loading() { return <Text>جاري التحميل</Text>; } class App extends React.Component { constructor() { super(); this.state = { ready: false }; } componentDidMount() { setTimeout(function () { this.setState({ ready: true }); }, 3000); } render() { return ( <View> { this.state.ready ? <Feed /> : <Loading /> } </View> ); } } export default App;
  14. مرحباً بك: يمكنك استخدام هذه المكتبة react-debounce-input فهي تفعل بالتحديد ما تريد import React from 'react'; import ReactDOM from 'react-dom'; import {DebounceInput} from 'react-debounce-input'; class App extends React.Component { state = { value: '' }; render() { return ( <div> <DebounceInput minLength={2} debounceTimeout={300} onChange={event => this.setState({value: event.target.value})} /> <p>Value: {this.state.value}</p> </div> ); } }
  15. مرحباً بك يجب تحويل ال payload ل formData قبل إرساله ليكون هكذا // تعريف متغير ليستقبل formData var payload = new FormData(); // إعطائه القيم payload.append('userName', 'usertest'); payload.append('userEmail', 'usertest@gmail.com'); axios({ method: 'post', url: '/addUser', data: payload, headers: { "Content-Type": "multipart/form-data" }, }) .then(function (response) { console.log(response); }) .catch(function (error) { console.log(error); });
  16. مرحباً بك: في البداية تعطي للحقل ref ويكون مثلا عبارة عن callback ref class App extends React.Component{ render() { return( <div> <input ref={input => { this.inputRef = input; }} /> </div> ); } } بعد ذلك تقوم بالتركيز على الحقل في أي مكان componentDidMount() { this.inputRef.focus(); }
  17. مرحباً بك: لكي تفهم الفرق يجب استخدام مثال أوضح مثل <Route path="/school" component={School} /> <Route path="/school/rooms" component={Rooms} /> بدون exact: عندما تكتب في المتصفح url/school سيقوم الراوتر بالبحث في قائمة ال routes لديك وإرجاع أول قيمة يجدها وهي أول route في المثال السابق وهذا جيد . لكن المشكلة ستظهر عندما تريد الذهب ل url/school/rooms سيبدأ الراوتر بالبحث وأيضاً سيقوم بإعادة أول قيمة يجدها وهي أول route في المثال السابق ( وهذا خطأ المفترض أن يرجع ثاني route ) وهذا بسبب المطابقة الجزئية في react router أي أن school جزء من school/rooms باستخدام exact: سيتأكد الراوتر من أن الصفحة التي تم تحميلها هي الصفحة التي لها نفس الرابط كما في الأمثلة السابقة ولن يعتمد المطابقة الجزئية
  18. مرحباً بك : أعتقد أنك تستخدم webpack ولذلك أنت تحتاج استخدام require <img src={require('./images/logo.jpeg')} />
  19. مرحباً بك: يمكنك استخدام هذه المكتبة فهي توفر لك المرونة في فعل ما تريد protected-react-routes-generator ولكن ستقوم بعمل configuration خاصة حيث أنك ستعطيها array وهي تقوم بإعادة ال routes لك تابع المثال // هذا ملف ال navigation import React from 'react'; import { Switch } from 'react-router-dom'; import { ConnectedRouter } from 'connected-react-router'; // Utility import RoutesConfiguration from 'protected-react-routes-generator'; // Routes import CoursePayment from '../Payment/Course'; import PaymentResult from '../Payment/PaymentResult'; function AppNavigation({ auth }) { // هذا الأوبجيكت يقوم بإرجاع routes // ستكون متاحة فقط للأشخاص الذين سجلو دخول const authorizedStructure = { // login وإذا قام أحد الأشخاص الذين قامو بتسجيل الدخول عبر كتابة المسار سيتم توجيهه لل fallbackPath: '/login', routes: [ { path: '/payment/result', component: <PaymentResult /> }, { path: '/course-payment/:id', component: <CoursePayment /> }, // في حالتك { path: '/protected', component: <Protected /> }, ] }; // هذا الأوبجيكت يقوم بإرجاع routes // ستكون متاحة فقط للأشخاص الذين لم يسجلو دخول const unAuthorizedStructure = { // dashboard وإذا قام أحد الأشخاص الذين قامو بتسجيل الدخول عبر كتابة المسار سيتم توجيهه لل fallbackPath: '/dashboard', routes: [ { path: '/signup', component: <SignUp /> }, { path: '/login/:resetAvailable?', component: <Login /> }, ] }; // هذا الأوبجيكت يقوم بإرجاع routes // ستكون متاحة لجميع الأشخاص سواء مسجل دخول أم لا // وكأمثلة const anonymousStructure = { routes: [ { path: '/', component: <Home /> }, { path: '/home', component: <Home /> }, { path: '/faqs', component: <Faqs /> }, { path: '/404', component: <PageNotFound /> }, // في حالتك { path: '/public', component: <Public /> }, ] }; return( <ConnectedRouter history={history}> <Switch> // هذه الدالة تأخذ جميع ما سبق ثم تقوم بإعادة الroutes النهائية {RoutesConfiguration({ isAuthenticated: auth.isAuthenticated, // هذه مهمه حيث تعطيه القيمة التي بناءاً عليها هل الشخص مسجل دخول أم لا anonymousStructure, authorizedStructure, unAuthorizedStructure, fallbackComponent: <PageNotFound /> })} </Switch> </ConnectedRouter> ); } const mapStateToProps = store => ({ auth: store.auth }); export default connect(mapStateToProps)(AppNavigation);
  20. مرحباً أحمد: لديك خطأ في تحميل مكتبة @react-native-community/masked-view حاول تثبيها منفردة كما يلي: npm install react-native-reanimated react-native-gesture-handler react-native-screens react-native-safe-area-context ثم npm install --force @react-native-community/masked-view
  21. مرحباً أحمد ما تريده هو ما نسميه pagination ونستخدم هذه الطريقة في الحالات المماثلة لحالتك ولكن يجب توافر شرط مهم وهو أ ال API يجب أن تدعم ال pagination (لكي تقول لها أنا في الصفحة الأولى وأريد ١٠ نتائج فقط أو أنا في الصفحة العشرين وأريد ٥ نتائج) في حالتك تحققت من وجود pagination يمكنك الإطلاع على طيقة الكتابة في قسم paginate من هنا الآن كل ما عليك فعله هو تعديل الرابط فقط ليكون هكذا // حيث // _page: هي الصفحة الحالية عند تحميل التطبيق // _limit: هو عدد البيانات التي تريد الحصول عليه عند مخاطبة السيرفر https://jsonplaceholder.typicode.com/photos?_page=0&_limit=50 أما إذا أردت أن تجعل الأمر ديناميكياً بحيث عند تضغط على زر معين يقوم بتحميل المزيد من البيانات فهذا يسمى (.SSP: Server Side Pagination ) وهي لعبة state لا أكثر ولا أقل فقط ستجعل _page, _limit ديناميكي وهذا كمثال class SSP extends React.Component { state= { pageIndex: 0, // الصفحة pageSize: 50, // عدد البيانات المستلمة data: [] // التي ستعطيها لل FlatList } componentDidMount() { this.loadData(); } loadData = () => { const {pageIndex, pageSize} = this.state; axios(`https://jsonplaceholder.typicode.com/photos?_page=${pageIndex}&_limit=${pageSize}`) .then(res => { // عند الحصول علي الداتا نقوم بإعطائها لل state // وندمجها بالبيانات القديمة (مهم جدا حتى لا نفقد البيانات التي تم تحميلها مسبقاً) this.setState(prevState => ({ data: prevState.data.concat(res.data) })); }) } onPressLoadMore =() => { // نحن الآن نريد الصفحة التالية ونريد ٥٠ نتيجة أخرى // لذلك نقوم بتحديث ال state this.setState({ pageIndex: this.state.pageIndex +1 }, () => { // بعدها نقوم بتحميل البيانات this.loadData(); }) } render() { return( // زر عند الضغط عليه يقوم بتحميل المزيد من البيانات <Button onPress={onPressLoadMore} /> // هنا ال flatList ); } }
  22. مرحباً بك: السبب في هذا أن التغيير في ال state يقوم بعمل rerender للمكون ككل وبالتالي فلو تم اعتمادها ك sync operation ستجد أن المتصفح لا يستجيب لأنه يقوم بتحديث المكون وهذا تصرف سيئ ومضر لل performance ولذلك تم اعتمادها ك async operation تشبيه بسيط ( إذا تم اعتمادها ك sync operation ) : ستشبه بحد كبير alert في جافاسكربت حيث إنها ستقوم بإيقاف المتصفح إلى أن تضغط موافق
  23. مرحباً بك: أولاً لديك خطأ في السطر التالي <tr>{ td(this.props.item) }</tr> حيث لا يوجد خاصية اسمها item هنا <TableRowItem key={item.id} data={item} columns={columnNames}/> أما بالنسبة للمشكلة فقد يكون هناك key مكرر من ال json نفسه الرجاء قم بمراجعة السطر الثاني لكل صف وتأكد أنهم مختلفين عن بعضهم this.props.data[c]
  24. مرحباً بك : ليس لديك وصول مباشر لجميع الدوال بداخل ال child ولكن يمكنك الوصول عن طريق إعطاء ref من ال child إلى ال parent ومن ثم استدعاء الدالة class Parent extends Component { fireChildAlert = () => { // التحقق من وجود مرجع للمكون Child // ومن ثم استدعاء الدالة بداخله this.childRef && this.childRef.getAlert(); } render() { return ( // ربط مرجع المكون الداخلي بالكون Parent <Child ref={ref => this.childRef = ref}> // تنفيذ الدالة عند الضغط <button onClick={() => this.fireChildAlert()}>Click</button> </Child> ); } } class Child extends Component { // إعطاء مرجع للمكونات التي تستخدم هذا المكون componentDidMount() { this.props.ref(this); } getAlert() { alert('clicked'); } render() { return ( <h1 >Child component</h1> ); } }
  25. مرحباً بك: لا يمكنك استخدام ال push عند التعديل على مصفوفة لأنها تقوم بعمل mutation وقد حذر فريق React من استعمالها ولكن عوضاً عن ذلك يمكنك استخدام concat this.setState({ array: this.state.array.concat('new Item') });
×
×
  • أضف...