我非常习惯于对组件进行分类,现在我尝试更多地习惯于钩子,所以我开始深入研究功能组件。
遇到一个棘手的问题,因为我一直无法将一个函数从一个功能组件传递到它的功能组件子组件。
在父组件中:
import React, { useState, useEffect } from 'react';
import { Link } from 'gatsby';
import { MenuList, MenuItem } from '@material-ui/core';
import { withCookies, Cookies } from 'react-cookie';
import { ExpandMore } from '@material-ui/icons';
import PropTypes from 'prop-types';
import styles from '../styles/nav.module.scss';
import NavDrawer from './navDrawer';
const activeStyle = {
color: '#445565',
backgroundColor: '#de1b',
borderColor: '#ced4da',
};
const NavMobile = (props) => {
const [isOpenProductsMenu, setIsOpenProductsMenu] = useState(false);
const [isOpenServicesMenu, setIsOpenServicesMenu] = useState(false);
const [isAdmin, setIsAdmin] = useState(false);
const { cookies, categories } = props;
const main = process.env.ROOT_CATEGORIES.split(',');
useEffect(() => {
if (cookies.get('roles')) {
const roles = cookies.get('roles');
setIsAdmin(!!roles.includes('ROLE_ADMIN') || roles.includes('ROLE_SUPERADMIN'));
}
});
const toggleProductsMenu = (isOpen) => {
if (event.type === 'keydown' && (event.key === 'Tab' || event.key === 'Shift')) {
return;
}
setIsOpenProductsMenu(isOpen);
};
const toggleServicesMenu = (isOpen) => {
if (event.type === 'keydown' && (event.key === 'Tab' || event.key === 'Shift')) {
return;
}
setIsOpenServicesMenu(isOpen);
};
return (
<MenuList className={styles.navMobile} style={{ padding: '0 10px 0 0' }}>
<MenuItem disableGutters>
<Link to="/" activeStyle={activeStyle}>Home</Link>
</MenuItem>
<MenuItem disableGutters>
<Link to="/search" activeStyle={activeStyle}>Search</Link>
</MenuItem>
<MenuItem
onMouseEnter={() => toggleProductsMenu(true)}
onMouseLeave={() => toggleProductsMenu(false)}
className={styles.overrideItem}
disableGutters
>
<NavDrawer
type={main[0]}
open={isOpenProductsMenu}
categories={categories}
toggleMenu={toggleProductsMenu}
/>
<Link to="/" onClick={(event) => event.preventDefault}>
<div className={styles.itemWrap}>
{main[0]}
<ExpandMore />
</div>
</Link>
</MenuItem>
<MenuItem
onMouseEnter={() => toggleServicesMenu(true)}
onMouseLeave={() => toggleServicesMenu(false)}
className={styles.overrideItem}
disableGutters
>
<NavDrawer
type={main[1]}
open={isOpenServicesMenu}
categories={categories}
toggleMenu={toggleServicesMenu}
/>
<Link to="/" onClick={(event) => event.preventDefault}>
<div className={styles.itemWrap}>
{main[1]}
<ExpandMore />
</div>
</Link>
</MenuItem>
{isAdmin ?
(
<MenuItem disableGutters>
<Link to="/admin" activeStyle={activeStyle}>Admin</Link>
</MenuItem>
) : null}
</MenuList>
);
};
NavMobile.propTypes = {
cookies: PropTypes.instanceOf(Cookies).isRequired,
categories: PropTypes.array.isRequired,
};
export default withCookies(NavMobile);但是,如果我试图像下面这样访问子组件中的道具,toggleMenu函数将不会出现在输出中;
当然,还会抛出一个type error。
export default function NavDrawer(props) {
const {
type,
open,
categories,
toggleMenu,
} = props;
console.log('props drawer', props);
<Drawer
id={`parentDrawer-${type}`}
onMouseEnter={() => setIsOpenSubDrawer(true)}
onMouseLeave={() => setIsOpenSubDrawer(false)}
className={classes.drawer}
variant="temporary"
open={open}
close={toggleMenu(false)}

我遗漏了什么?
发布于 2020-05-06 11:24:56
未定义toggleProductsMenu和toggleServicesMenu中的事件对象。
发布于 2020-05-06 10:55:26
因此,在我指出两个潜在的解决方案之前,需要注意的是,您在父函数调用中使用了render方法,并且render方法仅用于类函数,而不是无状态函数。
如果您想使用无状态函数,那么应该使用return。
查看文档中的差异
下面是截图:


现在,在解决方案中,Stateless Functions不应该有方法,添加它们通常被认为是不好的做法。我知道您想熟悉非类组件,但是使用这两种组件的混合并没有什么问题,这通常是应该这样做的。如果您想要添加方法,您应该使用Class Component并像(这个)那样执行它
class NavMobile extends Component {
constructor(props) {
super(props);
this.state = {
// Empty for now
}
}
toggleMenu = () => {
// Your code
}
render() {
return (
// More code
<Navbar toggleMenu={this.toggleMenu} />
// More code
)
}
}它被认为是错误实践的原因是因为每次调用组件时都会重新定义函数toggleMenu()。
如果您真的想继续这样做,那么应该在组件函数之外声明函数,所以只声明一次函数并使用相同的引用。
你应该尝试一些这样的方法:
const toggleMenu = (isOpen) => { ... };然后在组件中这样调用它
const NavMobile = (props) => {
return (
// Your code
<NavBar toggleMenu={toggleMenu.bind(null, propsYouWantToPass} />
)
}最后,您似乎在函数的内部寻找一个事件对象,例如(event.type === 'keydown'),但是没有传递这样的事件,因为在子组件NavBar中,您用false参数调用它。
如果有帮助请告诉我。
PS:我一开始对render和return的评论是针对您的代码进行编辑的。我还是会把它留给后人。
https://stackoverflow.com/questions/61632350
复制相似问题