How can i write data that is coming from Firebase

2019-04-18 03:22发布

Firstly, I'm working with React Native. I'm getting a data from Firebase and want to write to store (by Redux) quickly. But It doesn't work. You can find my all of codes below:

Function:

async getTumData (uid) {

    const {selectedGroupDetail, getSelectedGroupDetail} = this.props;
    var yeniGrupDetayi = {};
    await firebase.database().ref("/groups/"+uid).once('value').then(
      function(snapshot){
        yeniGrupDetayi = {...snapshot.val(), uid: uid};
      }).catch(e => console.log(e.message));

      console.log("FONKSIYON ICERISINDEKI ITEM ==>", yeniGrupDetayi);
      this.props.getSelectedGroupDetail(yeniGrupDetayi);
      console.log("ACTION'DAN GELEN ITEM ===>", selectedGroupDetail);

  }

Action:

export const getSelectedGroupDetail = (yeniGrupDetayi) => {
  return {
    type: GET_SELECTED_GROUP_DETAIL,
    payload: yeniGrupDetayi
  }
};

Reducer:

case GET_SELECTED_GROUP_DETAIL:
      return { ...state, selectedGroupDetail: action.payload}

Çıktı:

FONKSIYON ICERISINDEKI ITEM ==> {admin: {…}, groupDescription: "Yaygın inancın tersine, Lorem Ipsum rastgele sözcü…erini incelediğinde kesin bir kaynağa ulaşmıştır.", groupName: "İnsan Kaynakları", groupProfilePic: "", members: {…}, …}

ACTION'DAN GELEN ITEM ===> {}

There is a FlatList in my page and I defined a button in renderItem of FlatList. When i click to this button, getTumData() function is working.

When i click to this button first time, selectedGroupDetail is null. Second time, it shows previous data.

How can i write a data to Store quickly and fast?

Thanks,

1条回答
三岁会撩人
2楼-- · 2019-04-18 04:19

The thing is: - You're using both async/await, and then/catch in your code. - you're calling getSelectedGroupDetail before your async code resolves.

Fast Solution

getTumData =  (uid) => {

    const {selectedGroupDetail, getSelectedGroupDetail} = this.props;
    var yeniGrupDetayi = {};
    firebase.database().ref("/groups/"+uid).once('value').then(
     (snapshot) => {
        yeniGrupDetayi = {...snapshot.val(), uid: uid};
        this.props.getSelectedGroupDetail(yeniGrupDetayi);
      }).catch(e => console.log(e.message));   
  };

Better Solution:

1st: use Redux-Thunk middleware. 2nd: Move your Async code into your action creator: I mean this

async getTumData (uid) {

    const {selectedGroupDetail, getSelectedGroupDetail} = this.props;
    var yeniGrupDetayi = {};
    await firebase.database().ref("/groups/"+uid).once('value').then(
      function(snapshot){
        yeniGrupDetayi = {...snapshot.val(), uid: uid};
      }).catch(e => console.log(e.message));

      console.log("FONKSIYON ICERISINDEKI ITEM ==>", yeniGrupDetayi);
      this.props.getSelectedGroupDetail(yeniGrupDetayi);
      console.log("ACTION'DAN GELEN ITEM ===>", selectedGroupDetail);

  }

3rd: Your reducer should have another piece of data as an indicator for the time-gap before your selectedGroupDetail resolves:

// reducer initial state:
const INITIAL_STATE = { error: '', loading: false, selectedGroupDetail: null }

4th: Inside your action creator, you should dispatch 3 actions: ACTION_NAME_START // This should should only set loading to true in your reducer. ACTION_NAME_SUCCESS // set loading to false, and selectedGroupDetail to the new collection retured ACTION_NAME_FAIL // in case op failed set error

5th: Your React component, should display a loading indicator (spinner or somthing), and maybe disable FlatList button during the loading state.

// Action creator
export const myAction = () => (dispatch) => {
  dispatch({ type: ACTION_NAME_START });
  firebase.database().ref("/groups/"+uid).once('value').then(
  function(snapshot){
    yeniGrupDetayi = {...snapshot.val(), uid: uid};
    dispatch({ type: ACTION_NAME_SUCCESS, payload: yeniGrupDetayi  });

  }).catch(e => {
  dispatch({ type: ACTION_NAME_FAIL, payload: e.message });
});

};


// Reducer
const INITIAL_STATE = {
  loading: false,
  error: '',
  data: null,
};

export default (state = INITIAL_STATE, { type, payload }) => {
  switch (type) {
    case ACTION_NAME_START:
      return {
        ...state,
        error: '',
        loading: true,
        data: null,
      };

    case ACTION_NAME_SUCCESS:
      return {
        ...state,
        error: '',
        loading: false,
        data: payload,
      };

    case ACTION_NAME_FAIL:
      return {
        ...state,
        error: payload,
        loading: false,
        data: null,
      };

    default:
      return state;
  }
};
查看更多
登录 后发表回答