简体   繁体   中英

Stencil does not re-render component when @state() property changes

Does anyone know why my component doesn't re-render when this.searchText is cleared in clearSearchText() ?

Thanks in advance.

NOTE: I have already checked this related question but the answers don't work for me: stencil is not rerendeing component when @state() decorated property is changed

import { Component, h, Prop, State } from '@stencil/core';
import { faMagnifyingGlass, faX } from '@fortawesome/free-solid-svg-icons';

@Component({
  tag: 'search',
  styleUrl: 'search.scss',
  shadow: true,
})
export class Search {
  @State() searchText: string = null;

  private handleSearchTextChanged(event) {
    this.searchText = event.target.value;
  }

  /**
   * This prop points to the memory address of the *real* search function
   * on the parent of this component.
   */ 
  @Prop() doSearch: Function;

  @Prop() placeholderText: string;

  @Prop() buttonText: string;

  private handleSearchButtonPressed() {
    this.doSearch(this.searchText);
  }

  private handleEnterPressed(ev: KeyboardEvent) {
    if (ev.key === 'Enter') {
      this.doSearch(this.searchText);
    }
  }

  private clearSearchText = () => {
    this.searchText = ''; // this does NOT trigger a re-render
    console.log('got here'); // this is printed
  }

  render() {
    return (
      <div class="container">
        <h2>Find a Charity</h2>

        <div class="search-box">
          <svg xmlns="http://www.w3.org/2000/svg" class="icon" viewBox="0 0 512 512">
            <path d={faMagnifyingGlass.icon[4].toString()} />
          </svg>

          <input type="text" placeholder={this.placeholderText} onInput={event => this.handleSearchTextChanged(event)} onKeyDown={event => this.handleEnterPressed(event)} />

          <svg xmlns="http://www.w3.org/2000/svg" class="icon" id="x-icon" viewBox="0 0 512 512" onClick={() => this.clearSearchText()}>
            <path d={faX.icon[4].toString()} />
          </svg>
        </div>

        <button onClick={() => this.handleSearchButtonPressed()}>{this.buttonText}</button>
      </div>
    );
  }
}

I just created a quick demo: https://studio.webcomponents.dev/edit/MBPPrzr13SM3y37LEzog

The state property is actually cleared and the component is rerendered, the problem is that you're not assigning the new value to the input. To do that, add a value property to the text input:

render() {
  return (
    // ...
    <input type="text" value={this.searchText} placeholder={this.placeholderText} onInput={event => this.handleSearchTextChanged(event)} onKeyDown={event => this.handleEnterPressed(event)} />
    // ...
  );
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM