[作为传递函数,但未在React的子组件中执行
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了[作为传递函数,但未在React的子组件中执行相关的知识,希望对你有一定的参考价值。
我正在使用语义反应用户界面制作menu.以利用活动状态功能。在这种情况下,当您使用链接时,它会成为焦点或下划线。但是,在实现过程中,我将其作为道具传递给了子组件。见下文...
class DesktopContainer extends Component
state =
handleItemClick(event)
var name = event.target;
this.setState(
activeItem: name
)
render()
const GenericHeadingComponent, children, getWidth, isLoggedIn, logOutUser = this.props
const fixed, activeItem = this.state
return (
<Responsive getWidth=getWidth minWidth=Responsive.onlyTablet.minWidth>
<GenericIsUserLoggedInLink
isHomeButton=true
key="1"
name='home'
active=activeItem === 'home'
handleItemClick=this.handleItemClick /* is this correct */
mobile=false
/>
<GenericIsUserLoggedInLink
isLoggedIn=isLoggedIn
route="/profile"
anchorText="Profile"
key="2"
name='profile'
active=activeItem === 'profile'
handleItemClick=this.handleItemClick /* is this correct */
mobile=false
/>
<GenericIsUserLoggedInLink
isLoggedIn=isLoggedIn
route="/dashboard"
anchorText="Dashboard"
key="3"
name='dashboard'
active=activeItem === 'dashboard'
handleItemClick=this.handleItemClick /* is this correct */
mobile=false
/>
<Menu.Item position='right'>
<Button inverted=!fixed>
<GenericIsUserLoggedInLink
route="/login"
isLoggedIn=isLoggedIn
logOutUser=logOutUser
key="4" />
</Button>
<Button inverted=!fixed primary=fixed style= marginLeft: '0.5em' >
<Link href="/register">
<a>Register</a>
</Link>
</Button>
</Menu.Item>
</Container>
</Menu>
<GenericHeadingComponent />
</Segment>
</Visibility>
children
</Responsive>
)
DesktopContainer.propTypes =
children: PropTypes.node,
LayoutComponent.propTypes =
children: PropTypes.node,
var comparator;
const GenericIsUserLoggedInLink = React.memo(( isHomeButton, isLoggedIn, logOutUser, route, anchorText, mobile, active, handleItemClick ) =>
comparator = (prevProps, nextProps) =>
if (prevProps.isHomeButton !== nextProps.setProps.isHomeButton)
return true;
if (prevProps.isLoggedIn !== nextProps.setProps.route)
return true;
if (prevProps.anchorText !== nextProps.setProps.anchorText)
return true;
if (prevProps.active !== nextProps.setProps.active)
return true;
return false;
if (isHomeButton)
return <Menu.Item active=active onClick=() => handleItemClick><Link href="/"><a>Home</a></Link></Menu.Item>
if (isLoggedIn)
if (anchorText === undefined)
return <Link href="/"><a onClick=() => logOutUser()>Log out!</a></Link>
else if (anchorText && mobile)
console.log("active 1 ", active);
return <Menu.Item active=active><Link href=route><a >anchorText</a></Link></Menu.Item>
else if ((anchorText) && (!(mobile)))
console.log("mobile 2 ", mobile);
return <Menu.Item active=active onClick=() => handleItemClick><Link href=route><a >anchorText</a></Link></Menu.Item>
else if (anchorText)
return <Link href=route><a >anchorText</a></Link>
else
if (route === "/login")
return <Link href="/login"><a >Log in!</a></Link>
return null
, comparator);
我应该将状态下移到HOC吗?我没有收到错误,所以很困惑。
UPDATE 10/25/2019
决定只是添加来自控制台的最新反馈(错误)和更新的代码:
现在,当我单击/profile
链接/路由时,出现此错误:
index.js:1 Warning: validateDOMNesting(...): <a> cannot appear as a descendant of <a>.
in a (created by Link)
in Link
in a (created by MenuItem)
in MenuItem
in Unknown (created by DesktopContainer)
in div (created by Container)
in Container (created by DesktopContainer)
in div (created by Menu)
in Menu (created by DesktopContainer)
in div (created by Segment)
in Segment (created by DesktopContainer)
in div (created by Visibility)
in RefFindNode (created by Ref)
in Ref (created by Visibility)
in Visibility (created by DesktopContainer)
in div (created by Responsive)
in Responsive (created by DesktopContainer)
in DesktopContainer (created by LayoutComponent)
in LayoutComponent (created by Connect(LayoutComponent))
in Connect(LayoutComponent) (created by ProfilePage)
in ProfilePage (created by Profile)
in Profile (created by Connect(Profile))
in Connect(Profile) (created by Auth)
in Auth (created by MyApp)
in PersistGate (created by MyApp)
in Provider (created by MyApp)
in MyApp (created by AppWithRedux)
in AppWithRedux
in Suspense (created by AppContainer)
in Container (created by AppContainer)
in AppContainer
这是HOC:
var comparator;
const GenericIsUserLoggedInLink = React.memo(( isHomeButton, isLoggedIn, logOutUser, route, anchorText, mobile, activeItem, name, active, handleItemClick ) =>
comparator = (prevProps, nextProps) =>
if (prevProps.isHomeButton !== nextProps.setProps.isHomeButton)
return true;
if (prevProps.isLoggedIn !== nextProps.setProps.isLoggedIn)
return true;
if (prevProps.anchorText !== nextProps.setProps.anchorText)
return true;
if (prevProps.active !== nextProps.setProps.active)
return true;
if (prevProps.mobile !== nextProps.setProps.mobile)
return true;
if (prevProps.activeItem !== nextProps.setProps.activeItem)
return true;
if (prevProps.active !== nextProps.setProps.active)
return true;
return false;
if (isHomeButton)
console.log("active ", active);
return <Menu.Item name=name active=activeItem === name onClick=handleItemClick><Link href="/"><a>Home</a></Link></Menu.Item>
if (isLoggedIn)
if (anchorText === undefined)
return <Link href="/"><a onClick=() => logOutUser()>Log out!</a></Link>
else if (anchorText && mobile)
console.log("active 1 ", active);
console.log("mobile 1 ", mobile);
return <Menu.Item active=active><Link href=route><a >anchorText</a></Link></Menu.Item>
else if ((anchorText) && (!(mobile)))
console.log("mobile 2 ", mobile);
return <Menu.Item name=name active=activeItem === name onClick=handleItemClick><Link href=route><a >anchorText</a></Link></Menu.Item>
else if (anchorText)
return <Link href=route><a >anchorText</a></Link>
else
if (route === "/login")
return <Link href="/login"><a >Log in!</a></Link>
return null
, comparator);
这是类组件:
class DesktopContainer extends Component
state =
handleItemClick = (e, name ) => this.setState( activeItem: name )
render()
const GenericHeadingComponent, children, getWidth, isLoggedIn, logOutUser = this.props
const fixed, activeItem = this.state
return (
<Responsive getWidth=getWidth minWidth=Responsive.onlyTablet.minWidth>
<Visibility
once=false
onBottomPassed=this.showFixedMenu
onBottomPassedReverse=this.hideFixedMenu
>
<Segment
inverted
textAlign='center'
style= minHeight: 700, padding: '1em 0em'
vertical
>
<Menu
fixed=fixed ? 'top' : null
inverted=!fixed
pointing=!fixed
secondary=!fixed
size='large'
>
<Container>
<GenericIsUserLoggedInLink
isHomeButton=true
key="1"
name='home'
active=activeItem === 'home'
handleItemClick=this.handleItemClick
mobile=false
/>
<GenericIsUserLoggedInLink
isLoggedIn=isLoggedIn
route="/profile"
anchorText="Profile"
key="2"
name='profile'
active=activeItem === 'profile'
handleItemClick=this.handleItemClick
mobile=false
/>
<GenericIsUserLoggedInLink
isLoggedIn=isLoggedIn
route="/dashboard"
anchorText="Dashboard"
key="3"
name='dashboard'
active=activeItem === 'dashboard'
handleItemClick=this.handleItemClick
mobile=false
/>
<Menu.Item position='right'>
<Button inverted=!fixed>
<GenericIsUserLoggedInLink
route="/login"
isLoggedIn=isLoggedIn
logOutUser=logOutUser
key="4" />
</Button>
<Button inverted=!fixed primary=fixed style= marginLeft: '0.5em' >
<Link href="/register">
<a>Register</a>
</Link>
</Button>
</Menu.Item>
</Container>
</Menu>
<GenericHeadingComponent />
</Segment>
</Visibility>
children
</Responsive>
)
UPDATE 10/25/19 9:21 PM EST
我更新了我的HOC:
var comparator;
const GenericIsUserLoggedInLink = React.memo(( isHomeButton, isLoggedIn, logOutUser, route, anchorText, mobile, activeItem, name, handleItemClick ) =>
comparator = (prevProps, nextProps) =>
if (prevProps.isHomeButton !== nextProps.setProps.isHomeButton)
return true;
if (prevProps.isLoggedIn !== nextProps.setProps.isLoggedIn)
return true;
if (prevProps.mobile !== nextProps.setProps.mobile)
return true;
if (prevProps.active !== nextProps.setProps.active)
return true;
return false;
if (isHomeButton)
return <Link href="/"><Menu.Item name=name active=activeItem === name onClick=()=>handleItemClick(name)></Menu.Item></Link>
if (isLoggedIn)
if (anchorText === undefined)
return <Link href="/"><a onClick=() => logOutUser()>Log out!</a></Link>
else if (anchorText && mobile)
return <Link href=route><Menu.Item name=name active=activeItem === name>anchorText</Menu.Item></Link>
else if ((!(mobile)))
console.log("mobile 2 ", mobile);
return <Link href=route><Menu.Item name=name active=activeItem === name onClick=() => handleItemClick(name)></Menu.Item></Link>
else if (anchorText)
return <Link href=route><a>anchorText</a></Link>
else
if (route === "/login")
return <Link href="/login"><a>Log in!</a></Link>
return null
, comparator);
这是我的组件:
class DesktopContainer extends Component
state =
hideFixedMenu = () => this.setState( fixed: false )
showFixedMenu = () => this.setState( fixed: true )
handleItemClick = (e, name ) => this.setState( activeItem: name )
logOutUser = () =>
const logOutUser = this.props
logOutUser()
render()
const GenericHeadingComponent, children, getWidth, isLoggedIn, logOutUser = this.props
const fixed, activeItem = this.state
return (
<Responsive getWidth=getWidth minWidth=Responsive.onlyTablet.minWidth>
<Visibility
once=false
onBottomPassed=this.showFixedMenu
onBottomPassedReverse=this.hideFixedMenu
>
<Segment
inverted
textAlign='center'
style= minHeight: 700, padding: '1em 0em'
vertical
>
<Menu
fixed=fixed ? 'top' : null
inverted=!fixed
pointing=!fixed
secondary=!fixed
size='large'
>
<Container>
<GenericIsUserLoggedInLink
isHomeButton=true
key="1"
name='home'
activeItem=activeItem
handleItemClick=this.handleItemClick
mobile=false
/>
<GenericIsUserLoggedInLink
isLoggedIn=isLoggedIn
route="/profile"
anchorText="Profile"
key="2"
name='profile'
activeItem=activeItem
handleItemClick=this.handleItemClick
mobile=false
/>
<GenericIsUserLoggedInLink
isLoggedIn=isLoggedIn
route="/dashboard"
anchorText="Dashboard"
key="3"
name='dashboard'
activeItem=activeItem
handleItemClick=this.handleItemClick
mobile=false
/>
<Menu.Item position='right'>
<Button inverted=!fixed>
<GenericIsUserLoggedInLink
route="/login"
isLoggedIn=isLoggedIn
logOutUser=logOutUser
key="4" />
</Button>
<Button inverted=!fixed primary=fixed style= marginLeft: '0.5em' >
<Link href="/register">
<a>Register</a>
</Link>
</Button>
</Menu.Item>
</Container>
</Menu>
<GenericHeadingComponent />
</Segment>
</Visibility>
children
</Responsive>
)
但是现在出现此错误:
如果我正确传递了函数怎么办?
<GenericIsUserLoggedInLink
isHomeButton=true
key="1"
name='home'
activeItem=activeItem
handleItemClick=this.handleItemClick /* no ? */
mobile=false
/>
并正确使用它?
if (isHomeButton)
return <Link href="/"><Menu.Item name=name active=activeItem === name onClick=()=>handleItemClick(name)></Menu.Item></Link>
UPDATE 10/26/19
所以我知道这是有效的,因为控制台已输出...
else if ((!(mobile)))
console.log("name 1", name);
console.log("activeItem 1", activeItem);
return <Link href=route><Menu.Item name=name active=activeItem === name onClick=handleItemClick></Menu.Item></Link>
这里:
并且在我的父组件中,我添加了默认状态:
state = activeItem: 'home'
正确渲染的位置:
但是我仍然收到错误:
并且很好地,这是我在家长中使用的组件:
<GenericIsUserLoggedInLink
isHomeButton=true
key="1"
name='home'
activeItem=activeItem
handleItemClick=this.handleItemClick
mobile=false
/>
<GenericIsUserLoggedInLink
isLoggedIn=isLoggedIn
route="/profile"
anchorText="Profile"
key="2"
name='profile'
activeItem=activeItem
handleItemClick=this.handleItemClick
mobile=false
/>
<GenericIsUserLoggedInLink
isLoggedIn=isLoggedIn
route="/dashboard"
anchorText="Dashboard"
key="3"
name='dashboard'
activeItem=activeItem
handleItemClick=this.handleItemClick
mobile=false
/>
我应该在子组件中传递参数吗?
return <Link href="/"><Menu.Item name=name active=activeItem === name onClick=()=>handleItemClick(name)></Menu.Item></Link>
您可以尝试将构造函数中的方法绑定为
class DesktopContainer extends Component
constructor(props)
super(props);
this.state = ;
this.handleItemClick = this.handleItemClick.bind(this);
// remaining code
希望有帮助
首先,由于this
的上下文,在设置状态时,您的handleClick会导致错误。因此,我建议您将其绑定到构造函数中,或将其更改为这样的箭头函数-
handleItemClick = (e) =>
现在,我已将语义UI反应用于几个项目,并且单击事件的运行方式略有不同。根据文档-
Called on click. When passed, the component will render as an `a`
tag by default instead of a `div`.
onClick(event: SyntheticEvent, data: object)
event
React's original SyntheticEvent.
data
All props.
因此将您的onClick更改为onClick=handleItemClick
,然后
handleItemClick = (e, name ) => this.setState( activeItem: name )
希望对您有帮助。
更新:您的最新错误是由于链接内的<a>
标签。来自react-router
的链接就像一个标签,我们知道
<a href="1">
<a href="2"></a>
</a>
是无效的html。您可以参考此问题以获取更多信息Link cannot appear as a descendant of a link。
并且要解决您的错误,只需删除标签内的标签。
更新:-
最新错误是因为您要在handleItemClick中传递名称
if (isHomeButton)
return <Link href="/"><Menu.Item name=name active=activeItem === name onClick=handleItemClick></Menu.Item></Link> //change the onClick here//
以上是关于[作为传递函数,但未在React的子组件中执行的主要内容,如果未能解决你的问题,请参考以下文章
状态从父级更改为子级,但未反映到React Hook中的TextField中