#javascript #reactjs #typescript #styled-components
#javascript #reactjs #typescript #styled-компоненты
Вопрос:
Я знаю, что есть много вопросов, похожих на этот, но я уже пробовал каждый из них, и я все еще не могу заставить его работать.
Ну, я создаю свою собственную библиотеку пользовательского интерфейса, используя typescript и styled-компоненты. Честно говоря, я довольно новичок в TS, поэтому есть вероятность, что я пропустил что-то очевидное, поэтому любой совет будет оценен.
Теперь перейдем к тому, что имеет значение, вот это некоторый код:
/// THIS IS IN THE PROJECT I'M TRYING TO USE MY LIBRARY
<Button
size={4}
>
My cool button
</Button>
Как вы можете видеть, я передаю size
prop компоненту Button своей собственной библиотеки. Этот реквизит получен библиотекой здесь:
const Button = (props: IButtonProps) => {
return (
<StyledButton {...props}>
{props.leftIcon amp;amp; <ButtonIcon marginRight={props.iconSpacing}>{props.leftIcon}</ButtonIcon>}
{props.children}
{props.rightIcon amp;amp; <ButtonIcon marginLeft={props.iconSpacing}>{props.rightIcon}</ButtonIcon>}
</StyledButton>
)
}
И теперь, как вы можете видеть, у меня есть <StyledButton>
using styled-components, где я распространяю реквизит:
const StyledButton = styled.button<IButtonProps>`
// Other properties
padding: ${props => props.theme.paddings[props.size as SizeTypes ?? 4]};
// More properties
И проблема именно здесь. Когда я перехожу size={4}
из проекта, используя библиотеку, я получил ошибку в названии.
Конечно, я уже определил a 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 };
Если есть что-то еще, что могло бы дать вам больше информации, чтобы помочь мне, я, конечно, отредактирую сообщение.
Заранее спасибо!
Комментарии:
1. Можете ли вы создать jsfiddle?
2. Число не является допустимой ссылкой на имя свойства. У вас есть два варианта: 1. Заключите числа в кавычки (превратив их в строки) или используйте объект Map ( сравнение ), в котором указаны допустимые имена ключей.
3. Извините @Jashwant Я пытался использовать библиотеку, которую я создаю на ней, но не смог заставить ее работать. RandyCasburn Большое вам спасибо. Я собираюсь попробовать это. Я обновлю с помощью advanced КАК можно скорее.
4. Ну, я попробовал ваш ответ @RandyCasburn, но я все равно получил то же сообщение об ошибке.
5. Ну, я решил это. Вы были абсолютно правы @ghybs, я не вставлял свой компонент в
theme
объект, поэтому я не получал этот объект вStyled
const. Большое спасибо. Я думаю, что пиво, которое я выпил, создало такой базовый синапс в моем мозгу, лол. Я отредактирую свой ответ позже.
Ответ №1:
Я только что написал простой пример, который хорошо работает. Может быть, вы сможете найти различия между вашим и моим.
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>
);
}
Комментарии:
1. Я не уверен, как это решает мою текущую проблему, но я попробую. Все еще благодарен за ваш ответ.
2. Подсказка для вас:
console.log(props.theme)
в вашем стилизованном компоненте проверьте, были ли перезаписаны ваши отступы.
Ответ №2:
Как я уже сказал в комментариях, я допустил очевидную ошибку: Я забыл присвоить мои компоненты theme
object.
Итак, я создал новый ThemeWrapper.tsx
компонент с ThemeProvider
поставщиком, который передает theme
каждому children
prop (компонентам библиотеки):
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 amp;amp; <ButtonIcon mr={props.leftIconSpacing}>{props.leftIcon}</ButtonIcon>}
{props.children}
{props.rightIcon amp;amp; <ButtonIcon ml={props.rightIconSpacing}>{props.rightIcon}</ButtonIcon>}
</StyledButton>
</ThemeWrapper>
</>
)
}
Спасибо!