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

السؤال

نشر

السلام عليكم.

بعد تسجيل الدخول، يتوجه المستخدم ملفه الشخصي للقيام بإضافة ما يتوجب من معطيات. في هذه الحالة تكون المصفوفة profile فارغة لأنه لاتوجد بداخلها بيانات تتعلق بالملف الشخصي للمستخدم.

يقوم المستخدم إذن بإنشاء ملفه الشخصي بواسطة الكود التالي:

const profileSlice = createSlice({
  name: "profile",
  initialState: {
    profile: [],
    loading: false, 
    isProfileCreated: false,
  },
  reducers: {
    setProfile(state, action) {
        state.profile = action.payload
    },
    setLoading(state) {
        state.loading = true
    },
    clearLoading(state) {
        state.loading = false
    },
    setIsProfileCreated(state) {
        state.isProfileCreated = true;
        state.loading = false
    },
    clearIsProfileCreated(state) {
        state.isProfileCreated = false;
    },
  },
});

***

export function createProfile(newProfile) {
    return async(dispatch, getState) => {
        try {
            dispatch(profileActions.setLoading())
            const { data } = await axios.post(PROFILE_URL, newProfile, {
                headers: {
                    'x-auth-token': getState().auth.user.token
                }
            })
            dispatch(profileActions.setProfile(data))
            dispatch(profileActions.setIsProfileCreated())
            setTimeout(
              () => dispatch(profileActions.clearIsProfileCreated()),
              2000
            );
        } catch (error) {
            const err = error.response?.data.msg
            if (err) {
                dispatch(alertActions.createAlert(err));
                dispatch(alertActions.clearAlert(err));
            }

            const errors = error.response.data.errors 
            errors?.forEach((err) => {
                dispatch(alertActions.createAlert(err.msg));
                dispatch(alertActions.clearAlert(err.id));
            });
            dispatch(profileActions.clearLoading())
        }
    }
}

****

  const navigate = useNavigate();

  const dispatch = useDispatch();
  const { loading, isProfileCreated } = useSelector((state) => state.profile);
  const { alerts } = useSelector((state) => state.alert);

  const addNewProfile = (e) => {
    e.preventDefault();
    dispatch(
      createProfile({
        status,
        company,
        website,
        location,
        skills,
        githubusername,
        bio,
        twitter,
        facebook,
        instagram,
        linkedin,
        youtube,
      })
    );

    alerts.map((alert) => dispatch(alertActions.clearAlert(alert.id)));
  };

useEffect(() => {
    if (alerts.length > 0) {
      setShow(true);
      setTimeout(() => {
        setShow(false);
      }, 3000);
    }
  }, [alerts]);

  useEffect(() => {
    if (isProfileCreated) {
      navigate("/dashboard");
    }
  }, [navigate, isProfileCreated]);

هنا يتم إنشاء الملف الشخصي، ويتم تسجيل كافة المعطيات بقاعدة البيانات.

المشكل الذي أواجهه.

في الكود التالي

const { profile } = useSelector((state) => state.profile);
console.log(profile)

عندما أقوم بتحديث الصفحة تصبح profile مصفوفة فارغة.

أرجو المساعدة.

Recommended Posts

  • 0
نشر

مرحبا محمود 
أنت بالفعل تقوم بالإضافة إلى قاعدة البيانات وفى نفس الوقت تضيف فى المصفوفة ولكن عند تحديث الصفحة فى البداية لابد من جلب البيانات و إضافتها إلى المصفوفة ومن ثم إجراء العمليات على المصفوفة للقيام بهذه الإجراء اقترح عليك استخدام createAsyncThunk وهذه الدالة موجوده داخل الredux Toolkit لمعالجة العمليات الغير متزامنة في الأكشنز (actions) في Redux و تستطيع عن طريقها مشاركة البيانات التى تحصل عليها منAPI SERVER فى كل المكونات والوصول لها من أى مكون. 
وهذا مثال بسيط لاستخدامها

import { createAsyncThunk } from '@reduxjs/toolkit';
import axios from 'axios';

// تعريف ال async thunk
export const fetchData = createAsyncThunk(
  'data/fetchData', // نوع الأكشن
  async (arg, thunkAPI) => {
    try {
      const response = await axios.get('https://api.example.com/data');
      return response.data;
    } catch (error) {
      // التعامل مع الأخطاء، يمكنك إرسال أكشن آخر أو إلقاء الخطأ
      return thunkAPI.rejectWithValue(error.message);
    }
  }
);

// استخدام ال async thunk في الـ slice
import { createSlice } from '@reduxjs/toolkit';

const dataSlice = createSlice({
  name: 'data',
  initialState: {
    loading: false,
    data: null,
    error: null,
  },
  reducers: {},
  extraReducers: {
    [fetchData.pending]: (state) => {
      state.loading = true;
      state.error = null;
    },
    [fetchData.fulfilled]: (state, action) => {
      state.loading = false;
      state.data = action.payload;
    },
    [fetchData.rejected]: (state, action) => {
      state.loading = false;
      state.error = action.payload;
    },
  },
});

export default dataSlice.reducer;

حيث في هذا المثال:

  • createAsyncThunk تنشئ async thunk action creator بإسم fetchData. يأخذ هذا المنشئ نوع الأكشن ('data/fetchData') ودالة غير مزامنة تقوم بأداء عملية مزامنة (هنا، طلب بيانات من API).
  • createSlice تنشئ slice لتخزين الحالة (state) والأكشنز والريدوسيرز (reducers).
  • extraReducers تعرف كيفية التعامل مع نتائج ال async thunk مثل (التعليق)pending,  (الإكتمال)fulfilled, و(الرفض ) rejected.

بالتوفيق.. 

  • 0
نشر

مرحباً, أنت تقوم ببعض العمليات على profile slice , ولكن ما تواجهه أنه البيانات تزول عندما تقوم بتحديث الصفحة أو إعادة تحميلها بأي شكل , هذا بالطبع سيحدث كون redux toolkit بشكل إفتراضي لا تقوم بحفظ البيانات بشكل دائم في المتصفح ( local storage او اي شكل اخر ) , وإنما تقوم بحفظها بشكل مؤقت في المتصفح وعند إعادة تحميل الصفحة سوف تزول جميع العمليات التي قمت بها .

لحل هذه المشكلة ( او ما تبحث عنه ) يمكنك فعلها بطريقتين:

  • إما باستخدام localStorage , وتقوم بحفظ وتعديل البيانات في localStorage كلما قمت بتعديل redux toolkit slice , وفي كل مرة تقوم بتشغيل التطبيق تفحص إذا كان هناك بيانات مخزنة في localStorage فتقوم بإستردادها ل profile slice , يمكنك تعديل الكود لديك كالشكل التالي :

أولاً قم بتحديث create  profile action لتتضمن تخزين البيانات في local storage :

export function createProfile(newProfile) {
    return async(dispatch, getState) => {
        try {
            dispatch(profileActions.setLoading())
            const { data } = await axios.post(PROFILE_URL, newProfile, {
                headers: {
                    'x-auth-token': getState().auth.user.token
                }
            })
            dispatch(profileActions.setProfile(data))
            dispatch(profileActions.setIsProfileCreated())

            localStorage.setItem('profileData', JSON.stringify(data));

            setTimeout(
              () => dispatch(profileActions.clearIsProfileCreated()),
              2000
            );
        } catch (error) {
            const err = error.response?.data.msg
            if (err) {
                dispatch(alertActions.createAlert(err));
                dispatch(alertActions.clearAlert(err));
            }

            const errors = error.response.data.errors
            errors?.forEach((err) => {
                dispatch(alertActions.createAlert(err.msg));
                dispatch(alertActions.clearAlert(err.id));
            });
            dispatch(profileActions.clearLoading())
        }
    }
}

 

ثانياً ، عند بدء التطبيق، يمكنك التحقق مما إذا كانت هناك بيانات مخزنة واستخدامها , يمكنك وضع الكود التالي في layout او component الصفحة الاساسية .

useEffect(() => {
    const storedData = localStorage.getItem('profileData');
    if (storedData) {
        dispatch(profileActions.setProfile(JSON.parse(storedData)));
    }
}, []);

 

  • الطريقة الثانية , تسمى هذه التقنية redux persist , هي مكتبة تساعد في حفظ حالة التطبيق في تطبيقات React Redux عبر عملية التخزين المحلي. تسمح هذه المكتبة بالاحتفاظ بحالة Redux الحالية حتى بعد إعادة تحميل الصفحة أو إعادة فتح التطبيق عن طريق استخدام localStorage أو AsyncStorage في React Native.

انضم إلى النقاش

يمكنك أن تنشر الآن وتسجل لاحقًا. إذا كان لديك حساب، فسجل الدخول الآن لتنشر باسم حسابك.

زائر
أجب على هذا السؤال...

×   لقد أضفت محتوى بخط أو تنسيق مختلف.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   جرى استعادة المحتوى السابق..   امسح المحرر

×   You cannot paste images directly. Upload or insert images from URL.

  • إعلانات

  • تابعنا على



×
×
  • أضف...