Как передать функцию обратного вызова в элемент из React?

Я пытаюсь использовать компонент lit-element в своем проекте React, и я бы хотел передать функцию обратного вызова компоненту lit-element из React, но безуспешно.

Я пробовал несколько разных способов, таких как изменение типа свойства и передача функции в виде строки, но ни один из них не работает.

код компонента с подсветкой:

import { LitElement, html } from "lit-element";

class MyButton extends LitElement {
  static get properties() {
    return {
      clickHandler: {
        type: String
      },
      bar: {
        type: String
      }
    };
  }

  render() {
    const foo = this.clickHandler; //value is undefined
    const bar = this.bar; //value is "it's bar"
    return html`
      <button @click=${this.clickHandler}>click me</button>
    `;
  }
}

customElements.define("my-button", MyButton);

ответный код стороны:

<my-button clickHandler={() => alert("clicked")} bar="it's bar" />

Я установил точку останова в секции рендеринга компонента, и я вижу, что значение 'bar' правильно передается, но значение 'clickHandler' не определено.

У кого-нибудь есть идеи, как передать функцию из React в lit-element?

Спасибо!

3 ответа

Этот вопрос, вероятно, подходит не только для реакции. Это довольно общий вопрос, как передать обработчик от родительского к дочернему компоненту, будь то элемент lit или элемент html.

Согласно документу о собственности, https://lit-element.polymer-project.org/guide/properties

      <my-element 
  mystring="hello world"
  mynumber="5"
  mybool
  myobj='{"stuff":"hi"}'
  myarray='[1,2,3,4]'>
</my-element>

Не похоже, что он поддерживает функцию (обратный вызов) на данный момент. Так как же Element обрабатывает событие с родительского уровня?

Согласно документу по событию, https://lit-element.polymer-project.org/guide/events, вы можете отправить любое событие в дерево dom, включая вашего родителя. Domсистема событий намного шире, чем Reactопорная система.

      class MyElement extends LitElement {
    ...
    let event = new CustomEvent('my-event', {
      detail: {
        message: 'Something important happened'
      }
    });
    this.dispatchEvent(event);
}

а затем в освещенном или не освещенном контексте используйте следующее для обработки события:

      const myElement = document.querySelector('my-element');
myElement.addEventListener('my-event', (e) => {console.log(e)});

Таким образом, вы можете разрешить дочерним элементам запускать реализацию для родителя, что точно соответствует определению обратного вызова.

То, что я обнаружил, работает: добавление ссылки в компоненте реакции к освещенному элементу, а затем буквально установка свойства для него.

Итак, для следующего JSX:

<some-webcomponent ref={this.myRef}></some-webcomponent>

Вы можете передать свойство 'some-webcomponent' в ie componentDidMount:

componentDidMount () {
  const element = this.myRef.current;
  element.someCallback = () => // ...
}

Это не слишком красиво, но я бы тоже не считал это хаком. Требуется довольно много шаблонов, хотя:/

Вот полный компонент React для справки:

class MyComponent extends React.Component {   
  constructor(props) {     
    super(props);     
    this.myRef = React.createRef();   
  }   

  render() {     
    return <some-webcomponent ref={this.myRef}></some-webcomponent>;   
  } 

  componentDidMount() {
    const element = this.myRef.current;  
    element.someCallback = () => console.log(“call!”);
  }
}

Где горит элемент:

import { LitElement, html } from "lit-element";  

class SomeWebcomponent extends LitElement {
   static get properties() {    
     return {       
      someCallback: { type: Function }
     };
   }

   render() {     
     return html`       
       <button @click=${this.someCallback}>click me</button>     
     `;   
    } 
}  

customElements.define("some-webcomponent", SomeWebcomponent);

Взгляните на функцию щелчка по кнопке меню для набора pwa-стартер без избыточности по адресу https://github.com/Polymer/pwa-starter-kit/blob/template-no-redux/src/components/my-app.js. Я считаю, что это пример, который может работать на вас.

Другие вопросы по тегам