我把数据从child 1发送到parent然后再发送到child 2.现在有三件事我需要发送;值为天,月和年.只获取一个值就可以了,当我试图获取所有三个值时,我得到了一个TypeError.

家长:

import Results from "./Results";
import TopForm from "./TopForm";
import { useState } from "react";

function Hero() {
    const [dayValue, setDayValue] = useState("--");
    const [monthValue, setMonthValue] = useState("--");
    const [yearValue, setYearValue] = useState("--");

    return (
        <div className="font-poppins bg-light-grey p-2 h-screen w-screen">
            {/* Main Container */}
            <div className="container bg-white mt-16 max-w-[95%] md:max-w-2xl mx-auto p-10 rounded-xl rounded-br-3xl">
                <TopForm
                    // This does not work, Uncaught TypeError: callback is not a function
                    // callback={[setDayValue, setMonthValue, setYearValue]}

                    // This does work but only gets the dayValue
                    callback={setDayValue}
                />
                <Results
                    dayValue={dayValue}
                    monthValue={monthValue}
                    yearValue={yearValue}
                />
            </div>
        </div>
);
}

export default Hero;

子级1(获取数据的TopForm)

import { useState } from "react";

function TopForm({ callback }) {
const [error, setError] = useState(false);

const [dayText, setDayText] = useState("");
const [monthText, setMonthText] = useState("");
const [yearText, setYearText] = useState("");

const handleSubmit = (event) => {
    event.preventDefault();

    setDayText("");
    setMonthText("");
    setYearText("");
};

return (
    // Inputs Container
    <form onSubmit={handleSubmit}>
        {/* Upper Form */}
        <div className="container flex justify-center gap-4 md:max-w-lg">
            <div className="container w-1/3 flex flex-col">
                <label
                    htmlFor="day"
                    className={`if ${error} ? "text-red-400 text-sm mb-1 uppercase tracking-wide" : "text-smokey-grey"`}
                    id="day-label"
                >
                    Day
                </label>
                <input
                    type="number"
                    name="day"
                    id="day"
                    required
                    className="border-solid border-2 border-light-grey rounded-md p-3 text-lg outline-none focus:border-purple"
                    onChange={(event) => setDayText(event.target.value)}
                    value={dayText}
                />
                <div
                    id="day-error"
                    className="hidden text-xs text-red-400 mt-2"
                >
                    Must be a valid date
                </div>
            </div>

            <div className="container w-1/3 flex flex-col">
                <label
                    htmlFor="month"
                    id="month-label"
                    className="text-smokey-grey text-sm mb-1 uppercase tracking-wide"
                >
                    Month
                </label>
                <input
                    type="number"
                    name="month"
                    id="month"
                    required
                    className="border-solid border-2 border-light-grey rounded-md p-3 text-lg outline-none focus:border-purple"
                    onChange={(event) => setMonthText(event.target.value)}
                    value={monthText}
                />
                <div
                    id="month-error"
                    className="hidden text-xs text-red-400 mt-2"
                >
                    Must be a valid date
                </div>
            </div>

            <div className="container w-1/3 flex flex-col">
                <label
                    htmlFor="year"
                    id="year-label"
                    className="text-smokey-grey text-sm mb-1 uppercase tracking-wide"
                >
                    Year
                </label>
                <input
                    type="number"
                    name="year"
                    id="year"
                    required
                    className="border-solid border-2 border-light-grey rounded-md p-3 text-lg outline-none focus:border-purple"
                    onChange={(event) => setYearText(event.target.value)}
                    value={yearText}
                />
                <div
                    id="year-error"
                    className="hidden text-xs text-red-400 mt-2"
                >
                    Must be a valid date
                </div>
            </div>
        </div>

        {/* Line Arrow Container */}
        <div className="container my-20 flex justify-center relative">
            <hr className="border-light-grey w-full" />
            <button
                id="button"
                className="absolute top-1/2 left-1/2 transform -translate-x-1/2 -translate-y-1/2 bg-purple w-16 h-16 rounded-full flex items-center justify-center hover:scale-125 transition-all"
                type="submit"
                onClick={() => callback(dayText, monthText, yearText)}
            >
                <img
                    src="/images/icon-arrow.svg"
                    alt="arrow"
                    className="w-6"
                />
            </button>
        </div>
    </form>
);
}

export default TopForm;

子级2(结果,显示从TopForm收集的数据)

function Results({ dayValue, monthValue, yearValue }) {


return (
    // Results Container
    <div id="results-container" className="container">
        {/* Individual Container */}
        <div className="container flex">
            <span
                id="results-year"
                className="text-5xl italic font-bold text-purple mr-2"
            >
                {yearValue}
            </span>
            <p className="text-5xl italic font-bold mr-2">years</p>
        </div>

        <div className="container flex">
            <span
                id="results-month"
                className="text-5xl italic font-bold text-purple mr-2"
            >
                {monthValue}
            </span>
            <p className="text-5xl italic font-bold mr-2">months</p>
        </div>

        <div className="container flex">
            <span
                id="results-day"
                className="text-5xl italic font-bold text-purple mr-2"
            >
                {dayValue}
            </span>
            <p className="text-5xl italic font-bold mr-2">days</p>
        </div>
    </div>
);
}

export default Results;

推荐答案

我们可以通过跟踪您在TopForm中使用callbackprops 的位置来看到问题的问题:

onClick={() => callback(dayText, monthText, yearText)}

callback作为callback={[setDayValue, setMonthValue, setYearValue]}传递意味着callback是一个数组,因此您试图将数组作为函数调用,这是不正确的.

相反,您可以单独调用数组的内部函数,如:

onClick={() => {
  callback[0](dayText)
  callback[1](monthText)
  callback[2](yearText)
}}

const { useState } = React;

function TopForm({ callback }) {
  const [error, setError] = useState(false);

  const [dayText, setDayText] = useState("");
  const [monthText, setMonthText] = useState("");
  const [yearText, setYearText] = useState("");

  const handleSubmit = (event) => {
    event.preventDefault();

    setDayText("");
    setMonthText("");
    setYearText("");
  };

  return (
    // Inputs Container
    <form onSubmit={handleSubmit}>
      {/* Upper Form */}
      <div className="container flex justify-center gap-4 md:max-w-lg">
        <div className="container w-1/3 flex flex-col">
          <label
            htmlFor="day"
            className={`if ${error} ? "text-red-400 text-sm mb-1 uppercase tracking-wide" : "text-smokey-grey"`}
            id="day-label"
          >
            Day
          </label>
          <input
            type="number"
            name="day"
            id="day"
            required
            className="border-solid border-2 border-light-grey rounded-md p-3 text-lg outline-none focus:border-purple"
            onChange={(event) => setDayText(event.target.value)}
            value={dayText}
          />
          <div id="day-error" className="hidden text-xs text-red-400 mt-2">
            Must be a valid date
          </div>
        </div>

        <div className="container w-1/3 flex flex-col">
          <label
            htmlFor="month"
            id="month-label"
            className="text-smokey-grey text-sm mb-1 uppercase tracking-wide"
          >
            Month
          </label>
          <input
            type="number"
            name="month"
            id="month"
            required
            className="border-solid border-2 border-light-grey rounded-md p-3 text-lg outline-none focus:border-purple"
            onChange={(event) => setMonthText(event.target.value)}
            value={monthText}
          />
          <div id="month-error" className="hidden text-xs text-red-400 mt-2">
            Must be a valid date
          </div>
        </div>

        <div className="container w-1/3 flex flex-col">
          <label
            htmlFor="year"
            id="year-label"
            className="text-smokey-grey text-sm mb-1 uppercase tracking-wide"
          >
            Year
          </label>
          <input
            type="number"
            name="year"
            id="year"
            required
            className="border-solid border-2 border-light-grey rounded-md p-3 text-lg outline-none focus:border-purple"
            onChange={(event) => setYearText(event.target.value)}
            value={yearText}
          />
          <div id="year-error" className="hidden text-xs text-red-400 mt-2">
            Must be a valid date
          </div>
        </div>
      </div>

      {/* Line Arrow Container */}
      <div className="container my-20 flex justify-center relative">
        <hr className="border-light-grey w-full" />
        <button
          id="button"
          className="absolute top-1/2 left-1/2 transform -translate-x-1/2 -translate-y-1/2 bg-purple w-16 h-16 rounded-full flex items-center justify-center hover:scale-125 transition-all"
          type="submit"
          onClick={() => {
            callback[0](dayText)
            callback[1](monthText)
            callback[2](yearText)
          }}
        >
          <img src="/images/icon-arrow.svg" alt="arrow" className="w-6" />
        </button>
      </div>
    </form>
  );
}

function Results({ dayValue, monthValue, yearValue }) {
  return (
    // Results Container
    <div id="results-container" className="container">
      {/* Individual Container */}
      <div className="container flex">
        <span
          id="results-year"
          className="text-5xl italic font-bold text-purple mr-2"
        >
          {yearValue}
        </span>
        <p className="text-5xl italic font-bold mr-2">years</p>
      </div>

      <div className="container flex">
        <span
          id="results-month"
          className="text-5xl italic font-bold text-purple mr-2"
        >
          {monthValue}
        </span>
        <p className="text-5xl italic font-bold mr-2">months</p>
      </div>

      <div className="container flex">
        <span
          id="results-day"
          className="text-5xl italic font-bold text-purple mr-2"
        >
          {dayValue}
        </span>
        <p className="text-5xl italic font-bold mr-2">days</p>
      </div>
    </div>
  );
}

function Hero() {
  const [dayValue, setDayValue] = useState("--");
  const [monthValue, setMonthValue] = useState("--");
  const [yearValue, setYearValue] = useState("--");

  return (
    <div className="font-poppins bg-light-grey p-2 h-screen w-screen">
      {/* Main Container */}
      <div className="container bg-white mt-16 max-w-[95%] md:max-w-2xl mx-auto p-10 rounded-xl rounded-br-3xl">
        <TopForm
          callback={[setDayValue, setMonthValue, setYearValue]}
        />
        <Results
          dayValue={dayValue}
          monthValue={monthValue}
          yearValue={yearValue}
        />
      </div>
    </div>
  );
}

ReactDOM.createRoot(document.getElementById("app")).render(<Hero />);
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/18.2.0/umd/react.production.min.js" integrity="sha512-8Q6Y9XnTbOE+JNvjBQwJ2H8S+UV4uA6hiRykhdtIyDYZ2TprdNmWOUaKdGzOhyr4dCyk287OejbPvwl7lrfqrQ==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/18.2.0/umd/react-dom.production.min.js" integrity="sha512-MOCpqoRoisCTwJ8vQQiciZv0qcpROCidek3GTFS6KTk2+y7munJIlKCVkFCYY+p3ErYFXCjmFjnfTTRSC1OHWQ==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>

<div id="app"></div>

或者,您可以在Hero中创建一个回调函数,该函数接受三个参数并调用状态函数本身:

function Hero () {
  // …
  const setValues = (day, month, year) => {
    setDayValue(day);
    setMonthValue(month);
    setYearValue(year);
  };
  // …
  <TopForm callback={setValues} />

const { useState } = React;

function TopForm({ callback }) {
  const [error, setError] = useState(false);

  const [dayText, setDayText] = useState("");
  const [monthText, setMonthText] = useState("");
  const [yearText, setYearText] = useState("");

  const handleSubmit = (event) => {
    event.preventDefault();

    setDayText("");
    setMonthText("");
    setYearText("");
  };

  return (
    // Inputs Container
    <form onSubmit={handleSubmit}>
      {/* Upper Form */}
      <div className="container flex justify-center gap-4 md:max-w-lg">
        <div className="container w-1/3 flex flex-col">
          <label
            htmlFor="day"
            className={`if ${error} ? "text-red-400 text-sm mb-1 uppercase tracking-wide" : "text-smokey-grey"`}
            id="day-label"
          >
            Day
          </label>
          <input
            type="number"
            name="day"
            id="day"
            required
            className="border-solid border-2 border-light-grey rounded-md p-3 text-lg outline-none focus:border-purple"
            onChange={(event) => setDayText(event.target.value)}
            value={dayText}
          />
          <div id="day-error" className="hidden text-xs text-red-400 mt-2">
            Must be a valid date
          </div>
        </div>

        <div className="container w-1/3 flex flex-col">
          <label
            htmlFor="month"
            id="month-label"
            className="text-smokey-grey text-sm mb-1 uppercase tracking-wide"
          >
            Month
          </label>
          <input
            type="number"
            name="month"
            id="month"
            required
            className="border-solid border-2 border-light-grey rounded-md p-3 text-lg outline-none focus:border-purple"
            onChange={(event) => setMonthText(event.target.value)}
            value={monthText}
          />
          <div id="month-error" className="hidden text-xs text-red-400 mt-2">
            Must be a valid date
          </div>
        </div>

        <div className="container w-1/3 flex flex-col">
          <label
            htmlFor="year"
            id="year-label"
            className="text-smokey-grey text-sm mb-1 uppercase tracking-wide"
          >
            Year
          </label>
          <input
            type="number"
            name="year"
            id="year"
            required
            className="border-solid border-2 border-light-grey rounded-md p-3 text-lg outline-none focus:border-purple"
            onChange={(event) => setYearText(event.target.value)}
            value={yearText}
          />
          <div id="year-error" className="hidden text-xs text-red-400 mt-2">
            Must be a valid date
          </div>
        </div>
      </div>

      {/* Line Arrow Container */}
      <div className="container my-20 flex justify-center relative">
        <hr className="border-light-grey w-full" />
        <button
          id="button"
          className="absolute top-1/2 left-1/2 transform -translate-x-1/2 -translate-y-1/2 bg-purple w-16 h-16 rounded-full flex items-center justify-center hover:scale-125 transition-all"
          type="submit"
          onClick={() => callback(dayText, monthText, yearText)}
        >
          <img src="/images/icon-arrow.svg" alt="arrow" className="w-6" />
        </button>
      </div>
    </form>
  );
}

function Results({ dayValue, monthValue, yearValue }) {
  return (
    // Results Container
    <div id="results-container" className="container">
      {/* Individual Container */}
      <div className="container flex">
        <span
          id="results-year"
          className="text-5xl italic font-bold text-purple mr-2"
        >
          {yearValue}
        </span>
        <p className="text-5xl italic font-bold mr-2">years</p>
      </div>

      <div className="container flex">
        <span
          id="results-month"
          className="text-5xl italic font-bold text-purple mr-2"
        >
          {monthValue}
        </span>
        <p className="text-5xl italic font-bold mr-2">months</p>
      </div>

      <div className="container flex">
        <span
          id="results-day"
          className="text-5xl italic font-bold text-purple mr-2"
        >
          {dayValue}
        </span>
        <p className="text-5xl italic font-bold mr-2">days</p>
      </div>
    </div>
  );
}

function Hero() {
  const [dayValue, setDayValue] = useState("--");
  const [monthValue, setMonthValue] = useState("--");
  const [yearValue, setYearValue] = useState("--");
  
  const setValues = (day, month, year) => {
    setDayValue(day);
    setMonthValue(month);
    setYearValue(year);
  };

  return (
    <div className="font-poppins bg-light-grey p-2 h-screen w-screen">
      {/* Main Container */}
      <div className="container bg-white mt-16 max-w-[95%] md:max-w-2xl mx-auto p-10 rounded-xl rounded-br-3xl">
        <TopForm callback={setValues} />
        <Results
          dayValue={dayValue}
          monthValue={monthValue}
          yearValue={yearValue}
        />
      </div>
    </div>
  );
}

ReactDOM.createRoot(document.getElementById("app")).render(<Hero />);
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/18.2.0/umd/react.production.min.js" integrity="sha512-8Q6Y9XnTbOE+JNvjBQwJ2H8S+UV4uA6hiRykhdtIyDYZ2TprdNmWOUaKdGzOhyr4dCyk287OejbPvwl7lrfqrQ==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/18.2.0/umd/react-dom.production.min.js" integrity="sha512-MOCpqoRoisCTwJ8vQQiciZv0qcpROCidek3GTFS6KTk2+y7munJIlKCVkFCYY+p3ErYFXCjmFjnfTTRSC1OHWQ==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>

<div id="app"></div>

或者,您可以将这些函数作为单独的props 传递:

<TopForm
  setDay={setDayValue}
  setMonth={setMonthValue}
  setYear={setYearValue}
/>
function TopForm({ setDay, setMonth, setYear }) {
  // …
  onClick={() => {
    setDay(dayText)
    setMonth(monthText)
    setYear(yearText)
  }}
  // …
}

const { useState } = React;

function TopForm({ setDay, setMonth, setYear }) {
  const [error, setError] = useState(false);

  const [dayText, setDayText] = useState("");
  const [monthText, setMonthText] = useState("");
  const [yearText, setYearText] = useState("");

  const handleSubmit = (event) => {
    event.preventDefault();

    setDayText("");
    setMonthText("");
    setYearText("");
  };

  return (
    // Inputs Container
    <form onSubmit={handleSubmit}>
      {/* Upper Form */}
      <div className="container flex justify-center gap-4 md:max-w-lg">
        <div className="container w-1/3 flex flex-col">
          <label
            htmlFor="day"
            className={`if ${error} ? "text-red-400 text-sm mb-1 uppercase tracking-wide" : "text-smokey-grey"`}
            id="day-label"
          >
            Day
          </label>
          <input
            type="number"
            name="day"
            id="day"
            required
            className="border-solid border-2 border-light-grey rounded-md p-3 text-lg outline-none focus:border-purple"
            onChange={(event) => setDayText(event.target.value)}
            value={dayText}
          />
          <div id="day-error" className="hidden text-xs text-red-400 mt-2">
            Must be a valid date
          </div>
        </div>

        <div className="container w-1/3 flex flex-col">
          <label
            htmlFor="month"
            id="month-label"
            className="text-smokey-grey text-sm mb-1 uppercase tracking-wide"
          >
            Month
          </label>
          <input
            type="number"
            name="month"
            id="month"
            required
            className="border-solid border-2 border-light-grey rounded-md p-3 text-lg outline-none focus:border-purple"
            onChange={(event) => setMonthText(event.target.value)}
            value={monthText}
          />
          <div id="month-error" className="hidden text-xs text-red-400 mt-2">
            Must be a valid date
          </div>
        </div>

        <div className="container w-1/3 flex flex-col">
          <label
            htmlFor="year"
            id="year-label"
            className="text-smokey-grey text-sm mb-1 uppercase tracking-wide"
          >
            Year
          </label>
          <input
            type="number"
            name="year"
            id="year"
            required
            className="border-solid border-2 border-light-grey rounded-md p-3 text-lg outline-none focus:border-purple"
            onChange={(event) => setYearText(event.target.value)}
            value={yearText}
          />
          <div id="year-error" className="hidden text-xs text-red-400 mt-2">
            Must be a valid date
          </div>
        </div>
      </div>

      {/* Line Arrow Container */}
      <div className="container my-20 flex justify-center relative">
        <hr className="border-light-grey w-full" />
        <button
          id="button"
          className="absolute top-1/2 left-1/2 transform -translate-x-1/2 -translate-y-1/2 bg-purple w-16 h-16 rounded-full flex items-center justify-center hover:scale-125 transition-all"
          type="submit"
          onClick={() => {
            setDay(dayText)
            setMonth(monthText)
            setYear(yearText)
          }}
        >
          <img src="/images/icon-arrow.svg" alt="arrow" className="w-6" />
        </button>
      </div>
    </form>
  );
}

function Results({ dayValue, monthValue, yearValue }) {
  return (
    // Results Container
    <div id="results-container" className="container">
      {/* Individual Container */}
      <div className="container flex">
        <span
          id="results-year"
          className="text-5xl italic font-bold text-purple mr-2"
        >
          {yearValue}
        </span>
        <p className="text-5xl italic font-bold mr-2">years</p>
      </div>

      <div className="container flex">
        <span
          id="results-month"
          className="text-5xl italic font-bold text-purple mr-2"
        >
          {monthValue}
        </span>
        <p className="text-5xl italic font-bold mr-2">months</p>
      </div>

      <div className="container flex">
        <span
          id="results-day"
          className="text-5xl italic font-bold text-purple mr-2"
        >
          {dayValue}
        </span>
        <p className="text-5xl italic font-bold mr-2">days</p>
      </div>
    </div>
  );
}

function Hero() {
  const [dayValue, setDayValue] = useState("--");
  const [monthValue, setMonthValue] = useState("--");
  const [yearValue, setYearValue] = useState("--");

  return (
    <div className="font-poppins bg-light-grey p-2 h-screen w-screen">
      {/* Main Container */}
      <div className="container bg-white mt-16 max-w-[95%] md:max-w-2xl mx-auto p-10 rounded-xl rounded-br-3xl">
        <TopForm
          setDay={setDayValue}
          setMonth={setMonthValue}
          setYear={setYearValue}
        />
        <Results
          dayValue={dayValue}
          monthValue={monthValue}
          yearValue={yearValue}
        />
      </div>
    </div>
  );
}

ReactDOM.createRoot(document.getElementById("app")).render(<Hero />);
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/18.2.0/umd/react.production.min.js" integrity="sha512-8Q6Y9XnTbOE+JNvjBQwJ2H8S+UV4uA6hiRykhdtIyDYZ2TprdNmWOUaKdGzOhyr4dCyk287OejbPvwl7lrfqrQ==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/18.2.0/umd/react-dom.production.min.js" integrity="sha512-MOCpqoRoisCTwJ8vQQiciZv0qcpROCidek3GTFS6KTk2+y7munJIlKCVkFCYY+p3ErYFXCjmFjnfTTRSC1OHWQ==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>

<div id="app"></div>

Reactjs相关问答推荐

LocalStore未存储正确的数据

如何通过浏览器路由在单独的.jsx文件中使用MUI抽屉?

Antd V5组件自定义主题

Chakra UI:如何在选中状态下设置复选框 colored颜色

Syncfusion:带有 TabItemsDirective 的选项卡组件不显示任何内容

如何根据用户在react.js中的 Select , Select 多个心形图标?

React - 函数组件 - 点击两次问题处理

在按钮单击中将动态参数传递给 React Query

React + Redux:数据未正确传递给具有动态路由的组件

Redux Toolkit 配置,是否适用于全栈应用程序?

当每个元素都可拖动时,移动设备上的滚动列表出现问题

如何在 ChartJS 中操作 Y 轴

RTK 查询Mutations 在 StrictMode 中执行两次

如何保留我的下一个授权用户会话?所以我可以使用提供的 ID 在其他路由中获取数据

来自一个自定义 React Native 组件的样式从另一个自定义组件移除样式

在 React 中将路径与查询变量匹配

Cypress ,重试不再附加到 DOM 的元素

.filter() 函数在删除函数中创建循环 - React

如何跨微前端 React 应用管理状态管理?

如果查询不存在,如何返回所有产品?