Передача реквизитов в makeStyle в TS

#reactjs #typescript #material-ui #next.js

#reactjs #typescript #материал-пользовательский интерфейс #next.js

Вопрос:

Как я могу перейти post.mainImage к backgroundImage стилю.

Вот мой код;

 import React from 'react';
import { Post } from '../interfaces';
import { makeStyles, createStyles, Theme } from '@material-ui/core/styles';
import Container from '@material-ui/core/Container';

type Props = {
  post: Post;
}

const useStyles = makeStyles<Theme, Props>((theme: Theme) =>
  createStyles({
    root: {
      maxWidth: '100%',
      backgroundImage: ({ post }) => post.mainImage
    },
    date: {
      margin: theme.spacing(1),
      marginLeft: theme.spacing(2)
    },
    heroimage: {
      maxWidth: '100%',
      height: 'auto',
      objectFit: 'cover'
    }
  })
);

export default function HeroPost({ post }: Props) {
  const classes = useStyles({ post });
  return (
    <Container className={classes.root}>
      <img alt={post.title} src={post.mainImage} className={classes.heroimage} />
    </Container>
  );
}
  

Приведенный ниже код прошел без проблем из linter. Но все еще не удается получить backgroundImage значение спереди.

Комментарии:

1. Вы должны создать минимально воспроизводимый пример (предпочтительно на codesandbox )

Ответ №1:

Вы можете указать переменные типа для вызова makeStyles (обратите внимание, что первая должна быть типом темы, а вторая — типом реквизита):

 type Props = {
  post: Post;
};

const useStyles = makeStyles<Theme, Props>(theme =>
  createStyles({
    root: {
      maxWidth: '100%',
      backgroundImage: ({ post }) => `url("${post.mainImage}")`
    },
    // ...
  })
);

export default function HeroPost({ post }: Props) {
  const classes = useStyles({ post });

  return (
    // ...
  );
}
  

Комментарии:

1. Я знаю об этом взломе, но, как упоминал @Yatrix выше, можно передать с помощью JS, но не смог найти решение для TypeScript.

2. Изменен мой ответ — это должно устранить проблему с TS.

3. Это все еще не работает. Я использовал точку останова, чтобы проверить, post определена ли она на backgroundImage: ({ post }) => post.mainImage . К сожалению, это = undefined.

4. Демонстрация CodeSandbox

5. Похоже, что Typescript теряет предполагаемый тип при указании двух первых универсальных типов. Мой способ — сначала объявить стили как отдельный const ( styles ), а затем установить третий общий для makeStyles на keyof typeof styles .

Ответ №2:

Вам нужно передать реквизит с его типом непосредственно туда, где вы хотите получить к нему доступ. Это должно работать нормально.

 type BgProps = {
  mainImage: string;
}

const useStyles = makeStyles<Theme, Props>((theme: Theme) =>
  createStyles({
    root: {
      maxWidth: '100%',
      backgroundImage: (props: BgProps) => props.mainImage
    },
    date: {
      margin: theme.spacing(1),
      marginLeft: theme.spacing(2)
    }
  })
);
  

Ответ №3:

Попробуйте это: useStyles — это хук, который может принимать реквизит в параметрах и возвращать метод useStyles.

 const useStyles = (props: Props) => {
       const {post} = props;
    
       return makeStyles(theme => ({
           root: {
              maxWidth: '100%',
              backgroundImage: post.mainImage
           },
      }))
    } 
  

Ответ №4:

Вы получаете доступ к реквизитам следующим образом,

backgroundImage: props => props.backgroundImageProp

https://material-ui.com/styles/api/#returns-3

Комментарии:

1. Это не работает. Должно быть связано с TypeScript.

Ответ №5:

Попробуйте это с помощью Typescript :

    const useStyles = makeStyles(theme => ({
           root: ({mainImage}: {mainImage: string}) => ({
                 ...
                 backgroundImage: mainImage
           })        
    })
        
    const component: React.FC => {
        const classes = useStyles({mainImage})
         return ...
    }