无法读取未定义的属性(读取“4”)

Posted

技术标签:

【中文标题】无法读取未定义的属性(读取“4”)【英文标题】:Cannot read properties of undefined (reading '4') 【发布时间】:2022-01-15 08:41:45 【问题描述】:

我知道有很多类似的问题,但我已经尝试了每个问题,但仍然无法解决。

嗯,我正在使用 typescript 和 styled-components 构建自己的 ui 库。老实说,我是 TS 的新手,所以我可能会遗漏一些明显的东西,所以任何建议都将不胜感激。

现在开始重要的事情,这里是一些代码:

  /// THIS IS IN THE PROJECT I'M TRYING TO USE MY LIBRARY
  <Button 
        size=4
      >
        My cool button
  </Button>

如您所见,我将 size 属性传递给我自己的库的 Button 组件。这个道具在这里被图书馆接收:

const Button = (props: IButtonProps) => 
  return (
    <StyledButton ...props>
     props.leftIcon && <ButtonIcon marginRight=props.iconSpacing>props.leftIcon</ButtonIcon>
     props.children
     props.rightIcon && <ButtonIcon marginLeft=props.iconSpacing>props.rightIcon</ButtonIcon>
    </StyledButton>
  )

现在你可以看到我有 &lt;StyledButton&gt; 使用 styled-components 我正在传播道具:

const StyledButton = styled.button<IButtonProps>`
   // Other properties

  padding: $props => props.theme.paddings[props.size as SizeTypes ?? 4];

  // More properties

问题就在这里。当我使用库从项目中传递size=4 时,标题中出现错误。

当然,我已经用我的对象及其属性定义了 DeafultTheme

import 'styled-components'

declare module 'styled-components' 
  export interface DefaultTheme 

    // Some objects
   
    paddings: 
      1: string,
      2: string,
      3: string,
      4: string,
      5: string,
      6: string,
      7: string,
      8: string
    ;

    // More objects
  

还有一个 theme 正在使用它:

import  DefaultTheme  from 'styled-components';

const theme: DefaultTheme = 
  paddings: 
    1: '2px',
    2: '4px',
    3: '6px',
    4: '8px',
    5: '10px',
    6: '12px',
    7: '16px',
    8: '24px',
  
;

export  theme ;

最后,我的IButtonProps界面:

interface IButtonProps extends React.ComponentPropsWithoutRef<'button'> 
  onClick?: (evt: React.FormEvent<htmlElement>) => void;
  bg?: string;
  size: number;
  spacing: number;
  fontSize?: string;
  fontWeight?: string;
  borderRadius: number;
  color?: string;
  iconSpacing?: number;
  leftIcon?: React.ReactElement;
  rightIcon?: React.ReactElement;
  children?: React.ReactNode;


export  IButtonProps ;

如果有其他内容可以为您提供更多信息以帮助我,我当然会编辑帖子。

提前致谢!

【问题讨论】:

你能创建一个 jsfiddle 吗? 数字不是有效的属性名称Reference。您有两种选择:1. 用引号将数字括起来(使它们成为字符串)或使用 Map 对象 (comparison),其中数字是有效的键名。 对不起@Jashwant 我尝试使用我正在构建的库但无法使其工作。 RandyCasburn 非常感谢。我正在尝试的路上。我会尽快更新高级的。 好吧,我试过你的答案@RandyCasburn,但我仍然收到同样的错误信息。 好吧,我解决了。 @ghybs 你是绝对正确的,我没有用theme 对象嵌入我的组件,所以我没有在Styled const 中获取该对象。非常感谢。我想我喝的啤酒在我的大脑中形成了如此基本的突触,哈哈。我稍后会编辑我的答案。 【参考方案1】:

正如我在 cmets 中所说,我犯了一个明显的错误:我忘记使用 theme 对象嵌入我的组件。

所以我创建了一个新的ThemeWrapper.tsx 组件,其中包含一个ThemeProvider 提供程序,它将theme 传递给每个children 道具(库的组件):

import * as React from 'react';
import  ThemeProvider  from 'styled-components'
import  theme  from './theme';

const ThemeWrapper: React.FC = ( children ) => 
  return (
    <ThemeProvider theme=theme>
      children
    </ThemeProvider>
  )
;

export  ThemeWrapper ;

在我的Button.tsx 组件中:

const Button = (props: IButtonProps) => 
  return (
    <>
      <ThemeWrapper> --> Pay attention at this.
        <StyledButton ...props>
          props.leftIcon && <ButtonIcon mr=props.leftIconSpacing>props.leftIcon</ButtonIcon>
          props.children
          props.rightIcon && <ButtonIcon ml=props.rightIconSpacing>props.rightIcon</ButtonIcon>
        </StyledButton>
      </ThemeWrapper>
    </>
  )

谢谢!

【讨论】:

【参考方案2】:

我刚刚写了一个运行良好的简单示例。也许你能找到你和我的不同之处。

https://codesandbox.io/s/flamboyant-leaf-y4oyh?file=/src/App.js

import styled,  ThemeProvider  from "styled-components";

const paddingMap = 
  1: "10px",
  2: "20px",
  3: "30px",
  4: "40px"
;

const StyledButton = styled.button`
  font-size: $(props) => props.theme.padding[props.size ?? 4];
`;

const Button = (props) => 
  return <StyledButton ...props />;
;

export default function App() 
  return (
    <ThemeProvider theme= padding: paddingMap >
      <div className="App">
        <Button>my default button</Button>
        <Button size=4>my size 4 button</Button>
        <Button size=3>my size 3 button</Button>
        <Button size=2>my size 2 button</Button>
        <Button size=1>my size 1 button</Button>
      </div>
    </ThemeProvider>
  );


【讨论】:

我不确定它如何解决我当前的问题,但我会尝试一下。仍然感谢您的回答。 给您的提示:console.log(props.theme) 在您的样式组件中查看您的填充是否被覆盖。

以上是关于无法读取未定义的属性(读取“4”)的主要内容,如果未能解决你的问题,请参考以下文章

无法读取未定义的属性“参数”(React Router 4)

Vue 3 + Vue Router 4:TypeError:无法读取未定义的属性(读取“推送”)

Angular 4:使用自定义RouteReuseStrategy导致无法读取未定义的属性“prototype”

无法读取电子 javascript 中未定义的属性“on”

无法读取未定义类型错误的属性“推送”:无法读取未定义错误的属性“推送”

使用业力和 webpack 4 运行单元测试时无法读取未定义的属性“externalModuleIndicator”