【问题标题】:Components are not rendering while using .map() on array of objects in React在 React 中的对象数组上使用 .map() 时组件未呈现
【发布时间】:2021-08-13 11:39:47
【问题描述】:

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

我的组件

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 数据库就像

myproject-default-rtdb

| -成员

 |-MaApwTgulOH0bl1zSH

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

感谢您的帮助。

【问题讨论】:

  • 您需要在最顶层的组件上使用key-属性,在您的情况下是&lt;div className="select-members"&gt; 而不是&lt;div key={phoneNumber} classname="member" onClick={takeToBookNav}&gt;
  • 我按照你说的做了还是有同样的问题
  • `
    {membersDetail.map(({ name, phoneNumber }) => (
    {name}
    ))}
    `
  • 我的下一个猜测是membersDetail 在刷新后实际上是空的。你试过调试它,看看它是否真的有值吗?
  • 其实我应该在问题中提到它。我再次仔细检查了它,它控制了一个空数组,但有值。这里没有上传图片的选项

标签: reactjs firebase-realtime-database react-redux


【解决方案1】:

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

由于value event 会在发生更改时触发,因此您应该让该事件侦听器调度一个 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,但我认为您应该在应用启动时首先使用 set allMembers 或使用 onSnapShot 而不是 .on('value'

【讨论】:

    猜你喜欢
    • 2023-02-04
    • 2018-01-08
    • 2020-01-22
    • 2017-04-23
    • 1970-01-01
    • 2021-05-28
    • 1970-01-01
    • 2021-08-19
    • 1970-01-01
    相关资源
    最近更新 更多