【问题标题】:Type issue in React CloneElementReact CloneElement 中的类型问题
【发布时间】:2021-10-23 00:31:18
【问题描述】:

我正在使用 React Children 和 React Clone 元素,目标是在 Option 组件的 onClick 事件中触发包装器和 Select 组件中的方法。一切正常。但是我在调​​用 Option 组件时遇到类型错误。

代码:

import React, {
  useState,
  Dispatch,
  SetStateAction,
  Children,
  cloneElement,
  ReactElement,
  ReactNode
} from "react";

type OptionProps = {
  setSelectedInSelect: Dispatch<SetStateAction<string>>;
  setSelectedInWrapper: Dispatch<SetStateAction<string>>;
  fruit: string;
};

function Option({
  setSelectedInSelect,
  setSelectedInWrapper,
  fruit
}: OptionProps) {
  return (
    <li
      onClick={() => {
        setSelectedInSelect(fruit);
        setSelectedInWrapper(fruit);
      }}
    >
      {fruit}
    </li>
  );
}

type SelectProps = {
  children: ReactNode;
};

function Select({ children }: SelectProps) {
  const [selectedInSelect, setSelectedInSelect] = useState<string>("");
  return (
    <div>
      <div>
        <div>selected in select: {selectedInSelect}</div>
      </div>
      <ul>
        {Children.map(children, (child) => {
          return cloneElement(child as ReactElement, {
            setSelectedInSelect
          });
        })}
      </ul>
    </div>
  );
}

function Wrapper() {
  const [selectedInWrapper, setSelectedInWrapper] = useState<string>("");

  const fruits = ["Apple", "Orange"];

  return (
    <div style={{ margin: "20px" }}>
      <div style={{ marginBottom: "15px" }}>
        <div>selected in wrapper: {selectedInWrapper}</div>
      </div>
      <Select>
        {fruits.map((fruit) => {
          return (
            <Option // ERROR HERE
              key={fruit}
              fruit={fruit}
              setSelectedInWrapper={setSelectedInWrapper}
            />
          );
        })}
      </Select>
    </div>
  );
}

export default Wrapper;

错误是: Property 'setSelectedInSelect' is missing in type '{ key: string; fruit: string; setSelectedInWrapper: Dispatch&lt;SetStateAction&lt;string&gt;&gt;; }' but required in type 'OptionProps'.

当我克隆组件时,setSelectedInSelect 被传递给 Option。我怎样才能摆脱类型问题?

代码沙盒:https://codesandbox.io/s/infallible-swartz-fjnkm?file=/src/Select.tsx

【问题讨论】:

  • 有没有机会将此代码移动到沙箱以重现错误?
  • @DennisVash 在帖子末尾添加了代码框链接。

标签: reactjs typescript


【解决方案1】:

与其在 state 中保留两次相同的东西,不如将它从 wrapper 传递给 select 作为 prop?这样你就不需要第二次调用,也不需要克隆任何东西 键入 OptionProps = { setSelectedInWrapper: Dispatch; 水果:串; };

    function Option({
      setSelectedInWrapper,
      fruit
    }: OptionProps) {
      return (
        <li
          onClick={() => {
            setSelectedInWrapper(fruit);
          }}
        >
          {fruit}
        </li>
      );
    }

    type SelectProps = {
      children: ReactNode;
      selectedFruit: string
    };

    function Select({ children,selectedFruit }: SelectProps) {
     return (
        <div>
          <div>
            <div>selected in select: {selectedFruit}</div>
          </div>
          <ul>
            {children}
          </ul>
        </div>
      );
    }

    function Wrapper() {
      const [selectedInWrapper, setSelectedInWrapper] = useState<string>("");

      const fruits = ["Apple", "Orange"];

      return (
        <div style={{ margin: "20px" }}>
          <div style={{ marginBottom: "15px" }}>
            <div>selected in wrapper: {selectedInWrapper}</div>
          </div>
          <Select selectedFruit={selectedInWrapper}>
            {fruits.map((fruit) => {
              return (
                <Option
                  key={fruit}
                  fruit={fruit}
                  setSelectedInWrapper={setSelectedInWrapper}
                />
              );
            })}
          </Select>
        </div>
      );
    }

【讨论】:

  • 感谢@Nadia,但是如何将一些完全不同的道具或功能从 Select 传递给 Option?我将如何解决类型问题?这是我面临的主要问题。
  • 我建议你重新考虑你的方法,但如果你绝对必须这样做,你可以做一些事情,比如将 setSelectedInSelect={null!} 添加到选项
猜你喜欢
  • 2015-10-28
  • 1970-01-01
  • 2018-10-22
  • 2020-06-01
  • 1970-01-01
  • 2020-03-09
  • 2019-01-03
  • 2021-12-25
  • 2020-07-08
相关资源
最近更新 更多