Реквизит возвращает пустой объект в дочернем элементе

#reactjs

#reactjs

Вопрос:

Я совершенно новичок в React и в целом в программировании.

Мне нужно создать виджет приветствия, который отображает приветствие для пользователя в зависимости от времени суток. Имя пользователя извлекается в этот момент времени из локального файла JSON.

Это мой родительский компонент (виджет приветствия):

 import React from "react";
import Greeting from "../UserGreeting/Greeting";
import "./greeting-widget.scss";
import database from "../../../db.json";

export const Widget = () => {
  const user = database.userData;

  return (
    <div>
      <div className="clock">This will later be a clock</div>
      <Greeting name={user.userName} />
    </div>
  );
};

export default Widget;
 

Это мой дочерний компонент

 import React from "react";
import "./greeting.scss";
import PropTypes from "prop-types";

const Greeting = (props) => {
  console.log(props);

  const greetingText = () => {
    const now = new Date();
    const currentHour = now.getHours();
    if (currentHour >= 4 amp;amp; currentHour < 12) return "Good Morning";
    else if (currentHour >= 12 amp;amp; currentHour <= 17) return "Good Afternoon";
    else return "Good Evening";
  };

  return (
    <div className="greeting-wrapper">
      {greetingText()}, {props.name}.
    </div>
  );
};

export default Greeting;

Greeting.propTypes = {
  name: PropTypes.string,
};
 

Я получаю правильный результат в своем виджете приветствия.
Результат приветствия виджета

Код сборника рассказов родительского компонента:

 import React from "react";
import GreetingWidget from "../components/GreetingWidget/GreetingWidget";

export default {
  title: "Components / Greeting Widget",
};

export const Widget = () => {
  return <GreetingWidget />;
};
 

Но дочерний компонент не отображает имя пользователя, консоль.журнал также возвращает пустой объект.
Результат дочернего компонента

Сборник рассказов дочернего компонента

 import React from "react";
import GreetingComponent from "../components/UserGreeting/Greeting";

export default {
  title: "Components / User Greeting",
};

export const Greeting = () => {
  return <GreetingComponent />;
};
 

Я не понимаю, почему я получаю правильный результат в своем основном компоненте, но ничего в дочернем компоненте. Сначала я подумал, что, возможно, это потому, что я пытаюсь извлечь информацию из файла JSON, но я попытался жестко закодировать имя пользователя в родительском компоненте, а затем передать реквизиты дочернему компоненту. Но та же проблема все еще существовала. Что я делаю не так и что я должен сделать, чтобы улучшить это?

Спасибо за любую помощь.

Комментарии:

1. Пытались ли вы просто протестировать <Имя приветствия=»test» /> и увидеть в дочернем элементе, что консоль печатает «test»?

2. Я пробовал. Если я напечатаю console.log(props.name ) он возвращает значение undefined. Если я печатаю console.log(props), он возвращает пустой объект.

3. Пожалуйста, поделитесь кодами всех 4 компонентов.

4. Другие компоненты не будут использоваться в родительском компоненте.

Ответ №1:

Попробуйте это, я упростил код в том же файле, и, похоже, у меня это работает.

 import React from "react";
import PropTypes from "prop-types";

const Widget = () => {
  const user = "I am Test User";

  return (
    <div>
      <div className="clock">This will later be a clock</div>
      <Greeting name={user} />
    </div>
  );
};

const Greeting = (props) => {
  console.log(props);

  const greetingText = () => {
    const now = new Date();
    const currentHour = now.getHours();
    if (currentHour >= 4 amp;amp; currentHour < 12) return "Good Morning";
    else if (currentHour >= 12 amp;amp; currentHour <= 17) return "Good Afternoon";
    else return "Good Evening";
  };

  return (
    <div className="greeting-wrapper">
      {greetingText()}, {props.name}.
    </div>
  );
};

Greeting.propTypes = {
  name: PropTypes.string,
};

export default Widget;
 

Ответ №2:

тогда попробуйте сделать props destructuring . Вместо того, чтобы получать его напрямую как props или любой args , вы можете уничтожить их, чтобы {{ name }} :-

Однако, согласно вашему примеру выше, мне кажется, что ваша <Greeting name="user.name"/> работа просто находит Parent component причину, по которой вы отправляете реквизит name. Но если вы просто вызвали Child component ( Greeting ) само по себе, конечно props , оно будет пустым. Поскольку он должен name props быть передан им parent's component . Вот почему я думаю, что вы child component ничего не отображаете. если это так, то следующие исправления не смогут вам помочь.

Исправлено 1

  • child component
 import React from "react";
import "./greeting.scss";
import PropTypes from "prop-types";

const Greeting = ({ name }) => {
  console.log(name);

  const greetingText = () => {
    const now = new Date();
    const currentHour = now.getHours();
    if (currentHour >= 4 amp;amp; currentHour < 12) return "Good Morning";
    else if (currentHour >= 12 amp;amp; currentHour <= 17) return "Good Afternoon";
    else return "Good Evening";
  };

  return (
    <div className="greeting-wrapper">
      {greetingText()}, {name}.
    </div>
  );
};

export default Greeting;
 

Исправлено 2

Однако вы можете просто напрямую импортировать import database from "../../../db.json"; дочерний компонент ( Greeting.js ) вместо родительского компонента ( Widget.js ), например:-

  • Widget.js (родительский компонент), не нужно отправлять props
 import React from "react";
import Greeting from "../UserGreeting/Greeting";
import "./greeting-widget.scss";

export const Widget = () => {
  return (
    <div>
      <div className="clock">This will later be a clock</div>
      <Greeting />
    </div>
  );
};

export default Widget;
 
  • Greeting.js (дочерний компонент), импортируйте import database from "../../../db.json"; сюда вместо этого:-
 import React from "react";
import "./greeting.scss";
import PropTypes from "prop-types";
import database from "../../../db.json";

const Greeting = () => {
  const user = database.userData;

  const greetingText = () => {
    const now = new Date();
    const currentHour = now.getHours();
    if (currentHour >= 4 amp;amp; currentHour < 12) return "Good Morning";
    else if (currentHour >= 12 amp;amp; currentHour <= 17) return "Good Afternoon";
    else return "Good Evening";
  };

  return (
    <div className="greeting-wrapper">
      {greetingText()}, {user.name}.
    </div>
  );
};

export default Greeting;
 

Исправлено 3

Вам нужно будет импортировать import database from "../../../db.json"; ваши child component storybook Greeting потребности в компонентах since props или args хорошо функционировать. Итак:-

  • child component storybook
 import React from "react";
import GreetingComponent from "../components/UserGreeting/Greeting";
import database from "../../../db.json";

export default {
  title: "Components / User Greeting",
};

export const Greeting = () => {
  const user = database.userData;
  return <GreetingComponent name={user.data} />;
};
 

Вы можете игнорировать исправления 1 и исправления 2, если используете исправления 3

Комментарии:

1. Все та же проблема.

2. вы пытаетесь получить доступ к самому child component по себе?

3. Да, я создал отдельный сборник рассказов для родительского и дочернего компонентов (см. Отредактированный пост, где я добавил дополнительные фрагменты кода сборника рассказов). Может ли проблема быть в коде сборника рассказов дочернего компонента?

4. Я попробовал второй предложенный вами подход. Кажется, он работает нормально, когда реквизиты не отправляются, а база данных напрямую импортируется в дочерний компонент.

5. Да. Это будет работать. Во всяком случае, я обновил свой ответ выше. попробуйте исправить 3 . Я полагал, что это исправит ваши проблемы. вам не нужны исправления 1 и исправления 2 , если вы используете исправления 3