Material UI 自动完成上的 Typescript 相等问题

2024-01-14

数据存储为:

 { iso: "gb", label: "United Kingdom", country: "United Kingdom" },
 { iso: "fr", label: "France", country: "France" }

传递给自动完成的值是:

{ iso: "gb", label: "United Kingdom", country: "United Kingdom" }

控制台报告错误

Material-UI:提供给自动完成的值无效。 没有一个选项与{"label":"United Kingdom","iso":"gb","country":"United Kingdom"}.

报告类型错误value={}

输入“字符串|” ICountry' 不可分配给类型“ICountry | ICountry | ICountry”我国家[] |空 |不明确的'。 类型“string”不可分配给类型“ICountry |”我国家[] |空 |不明确的'。

问题:将数据传递给组件并没有将其设置为相应的选项,我不知道如何解决此问题。

问题代码和框:https://codesandbox.io/s/charming-firefly-zl3qd?file=/src/App.tsx https://codesandbox.io/s/charming-firefly-zl3qd?file=/src/App.tsx

import * as React from "react";
import { Box, Typography, TextField, Button } from "@material-ui/core";
import { Autocomplete } from "@material-ui/lab";
import "./styles.css";
import { countries } from "./countries";
import { investors } from "./investor";
import { Formik } from "formik";

interface ICountry {
  iso: string;
  country: string;
  label: string;
}

const isoToFlag = (isoCode: string) => {
  if (isoCode) {
    return typeof String.fromCodePoint !== "undefined"
      ? isoCode
          .toUpperCase()
          .replace(/./g, char =>
            String.fromCodePoint(char.charCodeAt(0) + 127397)
          )
      : isoCode;
  }
  return "";
};

const App: React.FC = () => {
  const investor = investors.find(element => element.id === "123");


  return (
    <div className="App">
      <Formik
        initialValues={{
          address: {
            country: investor?.legal.address.country ? investor.legal.address.country : '',
          }
        }}
        onSubmit={(values, actions) => {
          console.log({ values, actions });
          actions.setSubmitting(false);
        }}
      >
        {({ submitForm, isSubmitting, values, setFieldValue, setValues }) => {

          return (
            <form>

              <Autocomplete
                id="country"
                options={countries}
                getOptionLabel={option => option.label}
                value={values.address.country}
                renderOption={(option: ICountry) => (
                  <Box display="flex" flexDirection="row" alignItems="center">
                    <Box mr={1}>{isoToFlag(option.iso)}</Box>
                    <Box>
                      <Typography variant="body2">{option.label}</Typography>
                    </Box>
                  </Box>
                )}
                onChange={(e: object, value: any | null) => {
                  console.log('do the types match?', typeof value === typeof values.address.country);
                  console.log('do the objects match?', value === values.address.country);
                  console.log('the objects in question', value, values.address.country);
                  console.log("                  ");
                  setFieldValue("address.country", value);
                }}
                renderInput={params => (
                  <TextField
                    {...params}
                    name="address.country"
                    label="Country"
                    variant="outlined"
                    fullWidth
                  />
                )}
              />
              <Button
                variant="contained"
                size="large"
                color="primary"
                disabled={isSubmitting}
                onClick={submitForm}
              >
                Submit
              </Button>
            </form>
          );
        }}
      </Formik>
    </div>
  );
};

export default App;

国家.ts


import { ICountry } from "./investor";

export const countries: ICountry[] = [
  {
    iso: "gb",
    label: "United Kingdom",
    country: "United Kingdom"
  },
  {
    iso: "fr",
    label: "France",
    country: "France"
  }
];

完整消息来自Material-UI is:

Material-UI:提供给自动完成的值无效。 没有一个选项与{"label":"United Kingdom","iso":"gb","country":"United Kingdom"}。 您可以使用getOptionSelectedprop 来自定义相等测试。

默认的相等测试很简单===,因此,如果您的选项是对象,则您的值必须是这些确切对象之一才能匹配。具有相同值的不同对象将不匹配。

但正如消息告诉您的那样,您可以通过以下方式自定义相等测试getOptionSelected支柱。例如您可以指定:

getOptionSelected={(option, value) => option.iso === value.iso}

或者您可以对所有对象属性进行深度相等检查。

类型错误可以通过以下方式修复value={values.address.country as ICountry}.

这是使用 v4 的沙箱的工作版本:https://codesandbox.io/s/autocomplete-getoptionselected-b6n3s https://codesandbox.io/s/autocomplete-getoptionselected-b6n3s

这是一个工作版本,其中包含 v5 所需的修改:https://codesandbox.io/s/autocomplete-getoptionselected-forked-rfz625?file=/src/App.tsx https://codesandbox.io/s/autocomplete-getoptionselected-forked-rfz625?file=/src/App.tsx

v5版本使用isOptionEqualToValue代替getOptionSelected

                isOptionEqualToValue={(option, value) =>
                  option.iso === value.iso
                }

v5版本还改变了renderOption语法如中概述迁移指南 https://mui.com/material-ui/guides/migration-v4/#autocomplete.

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Material UI 自动完成上的 Typescript 相等问题 的相关文章

  • 使用输入更新 redux 状态

    如何从文本输入更新 redux 状态 我正在尝试用文本输入做一个非常简单的 Hello World 当有人在文本输入中输入内容时 它应该更新我商店的 searchTerm 值 我无法弄清楚这些事情 1 如何获取输入的值并将其传递到其 onC
  • 如何为 NextAuth.js 创建自定义 UI(使用 AWS Cognito)?

    是否可以为 AWS Cognito 提供自定义 UINextAuth js https next auth js org 当我使用 NextAuth js 调用 API 时 我看到这个 主观上丑陋的 屏幕 只有一个按钮可以将您重定向到真正的
  • 样式组件如何影响性能?

    使用样式组件是否比样式表更会降低 Web 应用程序的速度 如果我关心性能并且没有任何依赖于 props 的样式 我是否应该放弃样式组件并使用样式表 当您有很多小组件时 同时使用样式化组件渲染 性能开销可能会很有意义 绝对值得测试以删除小元素
  • “ReactNode”不是有效的 JSX 元素

    我有以下代码 代码沙箱 https codesandbox io s react typescript forked 50beyp file src App tsx import ComponentType ReactNode from r
  • 表单提交 ReactJS 时出现“类型错误:尝试获取资源时出现网络错误”

    我尝试在启用跨源的情况下从 API 获取一些数据 但收到此错误 同样的事情与JSON占位符 https jsonplaceholder typicode com 用于测试的在线 REST API 使用他们提供的示例 fetch https
  • 打字稿标记的枚举获取值

    我在下面标记了枚举 enum PermissionEnum SU 1 lt lt 0 1 Administrator 1 lt lt 1 2 User 1 lt lt 2 4 对于给定值 6 我怎样才能得到 string gt 管理员 用户
  • 反应模式 shouldCloseOnOverlayClick 不起作用

    我正在使用反应模式 点击叠加层后模式不会关闭 我为 isOpen 和 onRequestClose 提供了属性 但模式保持打开状态 closeModal gt this setState modalIsOpen false
  • Svelte:无法识别导入的 TypeScript 文件

    我正在尝试使用 Rollup 使用 Svelte 和 TypeScript 构建一个应用程序 当我尝试构建我的 Svelte 组件时 我似乎无法让它编译我的 ts包含的文件 svelte成分 我不断收到此错误 Error Unexpecte
  • Typescript 找不到模块

    我在 Typescript 的一个文件 upload ts 中有一个导出的模块 我无法在没有错误的情况下导入到另一个文件 application ts 中 另外 我无法导入 ExpressJS 这是Upload ts
  • 角度2中未定义的值

    我正在创建一个应用程序 在其中使用 Ag Grid api 在网页上列出我的数据库内容 Ag grid 有一个预定义的 api 来获取所选行的内容 这是我的代码 export class customer entryComponent pu
  • 具有两组子组件的 React 组件

    我正在创建一个组件 需要接收两组子组件并放置在组件的两个不同部分中 let CreditCardForm icons fields gt div div div div icons div div div fields div let Cr
  • 未强制执行 Typescript 抽象类静态方法

    我在 TypeScript 中有这个简单的代码 abstract class Config readonly NAME string readonly TITLE string static CoreInterface gt any cla
  • 添加 PayPal 付款方式 Ionic

    我正在尝试在我的用 Ionic 2 3 制作的应用程序上实现 PayPal 付款方式 我已经安装了 ionic cordova plugin add com paypal cordova mobilesdk npm install save
  • 获取 JSON 中的 HTML 以在 React 组件中呈现为 HTML

    试图找出如何让链接实际呈现为链接 现在 在我从 Json 文件中读取这行文本后 React 将超链接渲染为文字文本 而不将其渲染为链接 一些数据 json about John has a blog you can read a href
  • Menu.Item 中的 Antd 自动换行

    可以在 Menu Item 组件中应用自动换行吗 示例不起作用
  • 提及列表和表情符号顶部位置 (Draft.js)

    您能帮我如何将其位置从下到上更改吗 我想在文本顶部而不是底部显示提及列表 关于表情符号列表的同样问题 示例链接 https www draft js plugins com plugin emoji 你可以通过以下方式实现它position
  • 刷新或直接点击链接时找不到 React.js 页面

    我在此链接上有一个反应项目 https notchy cross 000webhostapp com https notchy cross 000webhostapp com 如果向下滚动 您会看到一个名为 产品类别 的部分 https i
  • FullCalendar-vue + Typescript:属性“getApi”不存在

    我尝试将 FullCalendar vue 与 Typescript 结合使用 但在访问其 API 时遇到错误 我的日历设置如下
  • 如何从 Chrome React Dev Tools 打开 VS code 中的组件文件?

    是否可以右键单击 React Dev 工具下可见的组件 然后单击 在 IDE 中显示 从而在 VSCode 中打开该文件 这将是有益的 因为我不必去寻找该组件 我经常想在 VS Code 中查看某个组件的源代码 但由于组件的模块化复用 代码
  • 使用打字稿的 Angular 6 的黄金布局?

    我在用黄金布局 https golden layout com 与 Angular 6 一起 如下本教程 https npm taobao org package embedded enterprises ng6 golden layout

随机推荐