[作为传递函数,但未在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>
  )
 

但是现在出现此错误:

enter image description here

如果我正确传递了函数怎么办?

        <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>
  

这里:

enter image description here

并且在我的父组件中,我添加了默认状态:

 state = activeItem: 'home'

正确渲染的位置:

enter image description here

但是我仍然收到错误:

enter image description here

并且很好地,这是我在家长中使用的组件:

        <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中

在 React 的子组件中将状态作为道具传递

从服务器获取数据并将值传递给 React 中的子组件(useEffect、useFetch..)

react 组件构建设计

当函数作为prop - React传递时,用酶调用函数

FlatList 不渲染从服务器获取的父组件数据,在 React Native 的子组件中