当我使用“ useCallback”时,出现TypeError错误
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了当我使用“ useCallback”时,出现TypeError错误相关的知识,希望对你有一定的参考价值。
我有const经验,可以在弹出窗口中创建6种经验。我应该向其中添加useCallback,但是当我走时我得到了错误。
这是我的组件经验
import React, memo, useCallback, useState from 'react';
import PropTypes from 'prop-types';
import makeStyles from '@material-ui/styles';
import Typography from '@material-ui/core/Typography';
import clsx from 'clsx';
import Button from '@material-ui/core/Button';
import Popover from '@material-ui/core/Popover';
import gastronomia from 'assets/experiences/gastronomia.jpg';
import productos from 'assets/experiences/productos.jpg';
import giftcard from 'assets/experiences/giftcard.jpg';
import diversion from 'assets/experiences/diversion.jpg';
import deporte from 'assets/experiences/deporte.jpg';
import belleza from 'assets/experiences/belleza.jpg';
import gastronomiaExperiences from 'data/gastronomia';
import productosExperiences from 'data/productos';
import giftcardExperiences from 'data/giftcard';
import diversionExperiences from 'data/diversion';
import deporteExperiences from 'data/deporte';
import bellezaExperiences from 'data/belleza';
// Proptypes definitions to the component.
const propTypes =
/** Custom root className. */
className: PropTypes.string,
;
// Default props definitions.
const defaultProps =
className: null,
;
// Component's styles
const useStyles = makeStyles(theme => (
root:
display: 'block',
margin: '0 auto',
maxWidth: '50%',
[theme.breakpoints.down('md')]:
maxWidth: '70%',
,
[theme.breakpoints.down('sm')]:
maxWidth: '100%',
,
'& .experiences-column':
display: 'inline-block',
verticalAlign: 'top',
textAlign: 'center',
'&.col1':
width: '36.31%',
[theme.breakpoints.down('sm')]:
width: 'initial',
,
,
'&.col2':
width: '63.69%',
[theme.breakpoints.down('sm')]:
width: 'initial',
,
,
'& .experience':
padding: 2,
position: 'relative',
'& img':
width: '100%',
display: 'block',
,
'& .experience-title':
position: 'absolute',
bottom: 30,
left: 0,
right: 0,
textAlign: 'center',
,
,
,
,
paper:
width: '50%',
left: '25% !important',
height: '280px',
'& img':
width: '100px',
padding: '0 10px 0 10px',
,
,
gastronomia:
backgroundColor: 'rgba(0,185,208,0.9)',
,
giftcard:
backgroundColor: 'rgba(221,165,174,0.9)',
,
deporte:
backgroundColor: 'rgba(189,143,205,0.9)',
,
productos:
backgroundColor: 'rgba(221,165,174,0.9)',
,
diversion:
backgroundColor: 'rgba(255,176,10,0.9)',
,
belleza:
backgroundColor: 'rgba(229,166,187,0.9)',
,
'@media screen and (max-width: 1024px)':
paper:
width: '70%',
left: '15% !important',
,
,
'@media screen and (max-width: 480px)':
paper:
width: '100%',
left: '0% !important',
height: '350px',
,
,
), name: 'ExperiencesStyle' );
*/const Experiences = memo(
(props) =>
const className = props;
const classes = useStyles(props);
const [anchorEl, setAnchorEl] = useState(null);
const handleClick = (event) =>
setAnchorEl(anchorEl ? null : event.currentTarget);
;
const handleClose = () =>
setAnchorEl(null);
;
// const open = Boolean(anchorEl);
const experience = useCallback((img, title, id, popoverCategory, anchorEl, classes, handleClick) => (
<div
className="experience"
aria-describedby=id
id=id
onClick=handleClick
onKeyDown=handleClick
role="button"
tabIndex="0"
>
<img
data-sizes="auto"
className="lazyload"
data-src=img
alt=title
/>
<div className="experience-title">
<Typography
color="textSecondary"
variant="subtitle2"
className="highlight highlight1"
display="inline"
>
title
</Typography>
</div>
<Popover
id=id
open=anchorEl && anchorEl.id === id
anchorEl=anchorEl
onClose=handleClose
classes=paper: clsx(classes.paper, classes[id])
>
<div>
<Button onClickAway=handleClose>x</Button>
<div>
popoverCategory.map(url => (
<img
key=url
data-sizes="auto"
className="lazyload"
src=url
alt=title
/>
))
</div>
</div>
</Popover>
</div>
), []);
return (
<div className=clsx(classes.root, className)>
<div className="experiences-column col1">
experience(gastronomia, 'GASTRONOMÍA', 'gastronomia', gastronomiaExperiences)
experience(giftcard, 'GIFT CARD', 'giftcard', giftcardExperiences)
experience(deporte, 'DEPORTE', 'deporte', deporteExperiences)
</div>
<div className="experiences-column col2">
experience(productos, 'PRODUCTOS', 'productos', productosExperiences)
experience(diversion, 'DIVERSIÓN', 'diversion', diversionExperiences)
experience(belleza, 'BELLEZA', 'belleza', bellezaExperiences)
</div>
</div>
);
,
);
错误是:
TypeError:无法读取未定义的属性'paper'
引用此行
classes=paper: clsx(classes.paper, classes[id])
将类添加到弹出框的纸类中的位置。
我不习惯使用Callback和new进行响应,所以我迷路了。
const experience = useCallback((img,title,id,popoverCategory,anchorEl,classes,handleClick)=>(
您创建的函数希望将7项内容传入其中。但是,当您使用它时,您只需传递4:
经验(美食家,'GASTRONOMÍA','美食家',美食家经验)
因此其余3个在函数内都未定义。在组件内部定义的anchorEl,class和handleClick变量在内部体验中不可见,因为这些变量已被“阴影化”。
因此,您可以通过简单地从函数定义中删除最后3个参数来停止隐藏变量:
const experience = useCallback((img, title, id, popoverCategory) => (
但是,我必须表示useCallback似乎并没有为您做任何事情。 useCallback的好处是,您可以让experience
变量从一个渲染到下一个成为相同的引用,但这似乎并不是您需要的功能。您的组件永远不会尝试比较experience
的引用,也不会将experience
传递到可能在shouldComponentUpdate或React.memo中进行检查的任何其他组件。
所以我建议您完全删除useCallback:
const experience = (image, title, id, popoverCategory) => (
以上是关于当我使用“ useCallback”时,出现TypeError错误的主要内容,如果未能解决你的问题,请参考以下文章