简体   繁体   中英

Firebase key return 'undefined' (ReactJS)

I'm trying to get a key back from firebase and to pass it to a component, but it returns undefined and i can't understand why..

Here is the component where i'm trying to get it work:

import React, { Component } from 'react';
import ProductItem from './ProductItem';

class ProductList extends Component {
  render() {
    console.log(this.props.productList);
    return (
      <ul className="product-list mt-5">
        {this.props.productList.map(function (item, idx) {
          return <ProductItem key={idx} pid={item.key} {...item} />;
        })}
      </ul>
    );
  }
}

export default ProductList;

In my <ProductItem> component if i console.log(this.props.pid) , it returns undefined.

Here is what contains this.props.productList : console.log 截图

EDIT: Here is the parent component:

import React, { Component } from 'react';
import ProductList from '../Product/ProductList';
import * as firebase from 'firebase/app';
import 'firebase/analytics';
import 'firebase/database';
import connectToStores from 'alt-utils/lib/connectToStores';
import ProductStore from '../../stores/ProductStore';
import Actions from '../../actions';

const firebaseConfig = {
  xxx
};
// Initialize Firebase
firebase.initializeApp(firebaseConfig);
firebase.analytics();

@connectToStores
class Homepage extends Component {
  constructor() {
    super();
    Actions.getProducts();
    Actions.getBrands();
    Actions.getSellers();
  }

  static getStores() {
    return [ProductStore];
  }

  static getPropsFromStores() {
    return ProductStore.getState();
  }

  render() {
    return (
      <>
        <section>
          <section className="container">
            {this.props.products ? <ProductList productList={this.props.products} /> : null}
          </section>
        </section>
      </>
    );
  }
}

export default Homepage;

Here is the actions:

import alt from '../alt';
import * as firebase from 'firebase/app';
import 'firebase/auth';
import 'firebase/database';
import _ from 'lodash';

class Actions {
  initSession() {
    return (dispatch) => {
      firebase.auth().onAuthStateChanged((firebaseUser) => {
        if (firebaseUser) {
          const user = {
            id: firebaseUser.uid,
            name: firebaseUser.displayName,
            avatar: firebaseUser.photoURL,
          };

          setTimeout(() => dispatch(user));
        } else {
          const user = null;
        }
      });
    };
  }

  login() {
    return (dispatch) => {
      var auth = firebase.auth();
      var provider = new firebase.auth.FacebookAuthProvider();
      auth
        .signInWithPopup(provider)
        .then(function (authData) {
          const user = {
            id: authData.user.uid,
            name: authData.user.displayName,
            avatar: authData.user.photoURL,
          };

          firebase.database().ref().child('users').child(authData.user.uid).set(user);

          console.log(authData);
          dispatch(user);
        })
        .catch(function (error) {
          // An error occurred
          return;
        });
    };
  }

  logout() {
    return (dispatch) => {
      firebase.auth().signOut();
      setTimeout(() => dispatch(null));
    };
  }

  getProducts() {
    return (dispatch) => {
      firebase
        .database()
        .ref('products')
        .on('value', function (snapshot) {
          const products = _.values(snapshot.val());
          dispatch(products);
        });
    };
  }

  addProduct(product) {
    return (dispatch) => {
      firebase.database().ref('products').push(product);
    };
  }

  getBrands() {
    return (dispatch) => {
      firebase
        .database()
        .ref('brands')
        .on('value', function (snapshot) {
          const brands = _.values(snapshot.val());
          dispatch(brands);
        });
    };
  }

  getSellers() {
    return (dispatch) => {
      firebase
        .database()
        .ref('sellers')
        .on('value', function (snapshot) {
          const sellers = _.values(snapshot.val());
          dispatch(sellers);
        });
    };
  }

  addVote(productId, userId) {
    return (dispatch) => {
      var firebaseRef = firebase.database().ref();
      firebaseRef = firebaseRef.child('products').child(productId).child('upvote');

      var vote = 0;
      firebase
        .database()
        .ref()
        .on('value', (snapshop) => {
          vote = snapshop.val();
        });
      firebaseRef.set(vote + 1);
    };
  }
}

export default alt.createActions(Actions);

firebase
  .database()
  .ref('products')
  .on('value', function (snapshot) {
    const products = _.values(snapshot.val());
    dispatch(products);
  });

This code, and others like it, are where you get data from Realtime Database. The snapshot object information about what was read from the database, and if you logged out snapshot.key , it would give you the key you appear to be looking for. However, currently the only thing you're doing with the snapshot is calling .val() on it. That's certainly useful (since it gives you the data in the snapshot), but it doesn't give you the key.

I don't have a full understanding of how your state is being managed; i don't, for example, know anything about the alt-utils library. So i can't give a full recommendation on what changes you should make. But in some form, you will need to access snapshot.key in this function and others like it. Then you'll either need to dispatch an action which saves those keys; or you'll need to merge the keys with the data you got from .val() , and then dispatch the merged data.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM