首页 > 解决方案 > 在 React 中的对象数组上使用 .map() 时组件未呈现

问题描述

组件一开始就按原样呈现。刷新页面后不会呈现。同样,如果我将密钥更改为不同的值,它会起作用,并且在刷新页面后它又消失了。

我的组件

const Book = ({ membersDetail }) => {

     const history = useHistory();

     const takeToBookNav = () => {

        history.push("/recordbook/booknav");

     };

return (

  <div className="book">

   {membersDetail.map(({ name, phoneNumber }) => (

   <div className="select-members">

       <div key={phoneNumber} classname="member" onClick={takeToBookNav}>{name}</div>

   </div>

   ))}

   </div>

  );

};

const mapStateToProps = createStructuredSelector({

   membersDetail: selectMembersList,

});

export default connect(mapStateToProps)(Book);

MEMBER_REDUCER

import MemberActionTypes from "./members-action.type";

const ININTIAL_STATE = {

  members: null,

  errorMessage: "",

  isGettingMembers: false,

  isAddingMembers: false,

  isRemovingMembers: false,

};

const memberReducer = (state = ININTIAL_STATE, action) => {

switch (action.type) {

  case MemberActionTypes.GET_MEMBER_START:

    return {

       ...state,

       isGettingMembers: true,

    };

 case MemberActionTypes.GET_MEMBER_SUCESS:

     return {

       ...state,

       members: action.payload,

       errorMessage: "",

   };

 case MemberActionTypes.GET_MEMBER_FAILURE:

     return {

       ...state,

       errorMessage: action.payload,

       isAddingMembers: false,

       isRemovingMembers: false,

       isGettingMembers: false,

  };

 default:

    return state;

  }

};

export default memberReducer;

传奇故事

export function* gettingMembers() {

  try {

      const membersList = yield getMembers();

      yield put(getMembersSucess(membersList));

      } catch (error) {

        yield put(getMembersFailure(error));

       }

     }

export function* getInintialMembersList() {

     yield put(getMembersStart());

}

export function* onSigningInSucess() {

   yield takeLatest(
 
    UserActionTypes.GOOGLE_SIGNIN_SUCESS,

    getInintialMembersList

  );

}

export function* onGettingMembers() {

    yield takeLatest(MemberActionTypes.GET_MEMBER_START, gettingMembers);

}

火力基地

//members data to firebase

const database = firebase.database(); //gets the database

const membersRef = database.ref("members");

export const createMember = (memberCredentials) => {

//pushing the object to the reference members

  membersRef.push(memberCredentials);

};

//get array of members from firebase

export const getMembers = () => {

  const membersList = [];

  membersRef.on("value", function (snapshot) {

  snapshot.forEach(function (childSnapshot) {

  const item = childSnapshot.val();

  item.key = childSnapshot.key;

  membersList.push(item);

});

 console.log(membersList);

});
 
return membersList;

};

firebase DATABASE 就像

我的项目-默认-rtdb

| -成员

 |-MaApwTgulOH0bl1zSH

       | -name: "Jhon Doe"
       |-phoneNumber: "984215789"

感谢您的帮助。

标签: reactjsfirebase-realtime-databasereact-redux

解决方案


该代码const membersList = yield getMembers();没有任何意义,因为getMembers您的 firebase 代码不是生成器。

由于value 事件在发生变化时触发,您应该让该事件侦听器调度一个 redux 操作来更新 redux 状态,并且您的 saga 可以被删除。您的 saga 看起来像是来自经典 api 的代码,您可以在其中获取数据,但 firebase 不能那样工作。

在您的组件中,您可以开始和停止收听成员的更新,但您不会像使用经典 REST api 那样获取数据。

所以你getMembers可以像下面的listenToMembers:

//your firebase code
let listening = false;
const onNewMembers = (() => {
  let allMembers = [];
  return (snapshot) => {
    //concat new members to existing members
    allMembers = allMembers.concat(
      snapshot.map(function (childSnapshot) {
        const item = childSnapshot.val();
        item.key = childSnapshot.key;
        return item;
      })
    );
    //store is your redux store
    store.dispatch(getMembersSucess(allMembers));
  };
})(); //IIFE that has all members
export const listenToMembers = () => {
  //check if we are already listening to members
  if (listening) {
    return;
  }
  listening = true;
  membersRef.on('value', onNewMembers);
};
//you can call this function if you're no longer interested in
//  changes in members
export const stopListenToMembers = () => {
  membersRef.off('value', onNewMembers);
};

我没有太多使用firebase,但我认为你应该在你的应用程序启动时首先设置 allMembers或者使用onSnapShot而不是.on('value'.


推荐阅读