Home > Blockchain >  Why is my component not receiving data from another?
Why is my component not receiving data from another?

Time:04-19

I have React Components:

My account.jsx

import "./myAccount.sass";
import { auth } from "../../firebaseConfig";
import {
  signOut,
  onAuthStateChanged,
} from "https://www.gstatic.com/firebasejs/9.6.0/firebase-auth.js";

import { useEffect, useState } from "react";
import { Hotel } from "../Hotel/Hotel";

function MyAccount(props) {
  const { isauth } = props;
  const { hotels = [] } = props;
  const [userEmail, setUserEmail] = useState([]);

  function logout() {
    signOut(auth);
    isauth(false);
    console.log("Successful logout");
  }

  function userInfo() {
    onAuthStateChanged(auth, (user) => {
      console.log(`user info: ${user.email}"`);
      setUserEmail(user.email);
    });
  }
  useEffect(() => {
    userInfo();
  }, []);
  return (
    <div>
      <h3>Hi, {userEmail}</h3>
      <button onClick={logout}>Logout...</button>
      <h4>Your reviews:</h4>
      <hr />
      <div className="Hotels">
        {hotels.map((hotel, id) => (
          <Hotel key={id} {...hotel} filter={true} user={userEmail} />
        ))}
      </div>
    </div>
  );
}

export default MyAccount;

Hotels.jsx

import starsMap from "../../starsMap";
import { useEffect, useState } from "react";
import "./hotel.sass";

function Hotel(props, filter = false, user = null) {
  const { name, img, localization, stars, review, author } = props;
  const [userEmail, setUserEmail] = useState(user);
  if (filter) {
    console.log(author, userEmail);
    if (author === user) {
      return (
        <div className="Hotel_card">
          <h2 className="Hotel_card-name">{name}</h2>
          <div className="Hotel_card_wrapper">
            <img className="Hotel_card-img" src={img} alt="hotel_img" />
            <h3 className="Hotel_card-localization">
              {/* Lat:{localization._lat}
              Long:{localization._lat} */}
              <button>Show on map</button>
            </h3>
            {starsMap.get(stars)}
          </div>
          <p className="Hotel_card-review">{review}</p>
          <h5 className="Hotel_card-author">Wroten by {author}</h5>
        </div>
      );
    }
  } else {
    return (
      <div className="Hotel_card">
        <h2 className="Hotel_card-name">{name}</h2>
        <div className="Hotel_card_wrapper">
          <img className="Hotel_card-img" src={img} alt="hotel_img" />
          <h3 className="Hotel_card-localization">
            {/* Lat:{localization._lat}
            Long:{localization._lat} */}
            <button>Show on map</button>
          </h3>
          {starsMap.get(stars)}
        </div>
        <p className="Hotel_card-review">{review}</p>
        <h5 className="Hotel_card-author">Wroten by {author}</h5>
      </div>
    );
  }
}

export { Hotel };

The MyAccount.jsx component passes two attributes to the Hotels.jsx component - filter={true} user={userEmail}. Hotels.jsx only sees filter={true}, user remains null for it. Question - why doesn't Hotels.jsx see the user={userEmail} passed to it?

If you look at the state userEmail in MyAccount.jsx, then the desired value is found this way, but it is lost at the moment it is transferred to Hotels.jsx

CodePudding user response:

It's because you are using an intermediate useState in the Hotel.jsx file and you are not receiving correctly the props

const [userEmail, setUserEmail] = useState(user);

remove that line (it seems that you are not using it anyway) and change in the Hotels.jsx component the prop user to userEmail:

function Hotel({filter = false, userEmail = null, ...props})

CodePudding user response:

A React Functional Component, is a function that returns some JSX code. When you write it like:

<Hotel key={id} {...hotel} filter={true} user={userEmail} />

This is JSX, and this code gets converted to React first class API:

React.createElement(
  Hotel,
  [props],
  [...children]
)

props are filter, user and whatever comes out of {...hotel}.

The React.createElement just takes props and children ( if at all ), and passes an object to your Hotel function with them all inside, remember that props is an object:

Hotel(props)

Being an object, when you want to recall your props from within your Component, you have two possible ways:

function Hotel (props) {
  console.log(props.filter, props.user)
}

or through destructuring them directly when declaring them:

function Hotel ({filter, user}) {
  console.log(filter, user)
}

If you are passing other props that you don't want to name directly:

function Hotel ({filter, user, ...props}) {
  console.log(filter, user, props)
}
  • Related