admin管理员组

文章数量:1327849

Hi everyone.

I have:

import React,{useState, useEffect} from 'react'

/* Styles */
import css from './MyComponent.module.sass'

const MyComponent= ({children, className, ...props}) => {
    const onOver = (e) => {
        console.log(e.target.offsetLeft);
    }

    //And here i need to add onOver function to each "children" element as onMouseOver event

    return(
        <ul className={`${css.MyComponentWrap} ${className}`}>
            <div className={css.MyComponent}></div>
            {children}
        </ul>
    );
}

export default MyComponent;

How can I do it?

I searched the Internet for an answer, but did not find anything suitable. Is it possible to make all the code in this ponent so that nothing needs to be added to the ponent in which it will be used?

P.S. sorry for my bad english))

upd.

const AnotherComponent = () =>{

    //here is a huge map function

    let mapResult;
    return (
        <MyComponent>
            {mapResult}
        </MyComponent>
    );
}

I have a huge and hard maping thats why I cannot use @Kox `s answer.

and i need some thing like loop in "MyComponent" and add event or pass it as props.

Actually I can but i thing it not a best solution

Hi everyone.

I have:

import React,{useState, useEffect} from 'react'

/* Styles */
import css from './MyComponent.module.sass'

const MyComponent= ({children, className, ...props}) => {
    const onOver = (e) => {
        console.log(e.target.offsetLeft);
    }

    //And here i need to add onOver function to each "children" element as onMouseOver event

    return(
        <ul className={`${css.MyComponentWrap} ${className}`}>
            <div className={css.MyComponent}></div>
            {children}
        </ul>
    );
}

export default MyComponent;

How can I do it?

I searched the Internet for an answer, but did not find anything suitable. Is it possible to make all the code in this ponent so that nothing needs to be added to the ponent in which it will be used?

P.S. sorry for my bad english))

upd.

const AnotherComponent = () =>{

    //here is a huge map function

    let mapResult;
    return (
        <MyComponent>
            {mapResult}
        </MyComponent>
    );
}

I have a huge and hard maping thats why I cannot use @Kox `s answer.

and i need some thing like loop in "MyComponent" and add event or pass it as props.

Actually I can but i thing it not a best solution

Share Improve this question edited Mar 26, 2020 at 16:49 Анар Лятифов asked Mar 26, 2020 at 16:18 Анар ЛятифовАнар Лятифов 691 silver badge6 bronze badges 5
  • Does this answer your question? How to pass props to {this.props.children} – n1stre Commented Mar 26, 2020 at 16:20
  • 1 you need to specify what is children and also provide what you have tried so far – Abdullah Abid Commented Mar 26, 2020 at 16:25
  • @streletss see upd. – Анар Лятифов Commented Mar 26, 2020 at 16:51
  • @Abdullah Abid updated – Анар Лятифов Commented Mar 26, 2020 at 16:51
  • 1 still, your question looks like a duplicate to me. inside MyComponent instead of {children} just do {React.Children.map(children, child => React.cloneElement(child, { onMouseOver: onOver }) )} – n1stre Commented Mar 26, 2020 at 16:59
Add a ment  | 

3 Answers 3

Reset to default 4

If you want to pas prop to your children, use React.PureComponent and React.Children API

class MyComponent extends React.PureComponent {
  onOver = event => {
    //do what u want with you event
  }

  render() {
    const childrenHavingOnOverFunction = 
      React.Children.map(this.props.children, child => {
         return React.cloneElement(child, { onOver: this.onOver })
      }
    );

    return (
        <ul className={`${css.MyComponentWrap} ${className}`}>
            <div className={css.MyComponent}></div>
            {childrenHavingOnOverFunction}
        </ul>
    )

  }
};

Any reason you can't attach the listener to the parent (here: ul), and use target to identify which element has been "mouseovered"?

function App() {
  return (
    <MyComponent>
      <li>Bob</li>
      <li className="tab">John</li>
      <li>Sally</li>
    </MyComponent>
  );
}

function MyComponent({ children }) {
  
  function handleClick(e) {
    const { target: { offsetLeft } } = e;
    console.log(offsetLeft);
  }
  
  return (
    <ul onMouseOver={handleClick}>
      {children}
    </ul>
  );
}

// Render it
ReactDOM.render(
  <App />,
  document.getElementById("react")
);
ul { width: 100px; }
li:hover { background-color: #efefef; }
.tab { margin-left: 1em; }
<script src="https://cdnjs.cloudflare./ajax/libs/react/16.8.4/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare./ajax/libs/react-dom/16.8.4/umd/react-dom.production.min.js"></script>
<div id="react"></div>

This seems like a nice use case for render props (via children prop).

Let your ponent return this:

return(
  <ul className={`${css.MyComponentWrap} ${className}`}>
   <div className={css.MyComponent}></div>
   {children(onOver)}
  </ul>
);

Now MyComponent should accept its children as a function to render:

<MyComponent>
{(onOver) => {
  // your children ponents now have access to onOver function
}}
</MyComponent>

本文标签: javascriptReact js add event listener for each quotchildrenquotStack Overflow