Обновление атрибута lit-element из компонента React не обновляет веб-компонент - PullRequest
0 голосов
/ 02 апреля 2020

Я использую веб-компоненты с освещенным элементом внутри приложения React.

Когда я обновляю атрибут веб-компонента из компонента React с помощью JSON Stringified объекта, веб-компонент не обновляется, пока я не принудительно заставлю обновление метода веб-компонента attributeChangedCallback.

Реагирующий компонент

const AppHeader: React.SFC<AppHeaderProps> = () => {
    return (
        <userContext.Consumer>
            {({ user }) => {
                const userName: string = (user as UserType)?.given_name || '';
                const greetings = userName ? `Hello ${userName}!` : '';

                return (
                    <app-header>
                        <h1 slot="title">React all-in-one starter</h1>
                        <div style={rightSideStyles} slot="right-side">
                            <p className="username">{greetings}</p>
                            <app-login user={JSON.stringify(user)} />
                        </div>
                    </app-header>
                );
            }}
        </userContext.Consumer>
    );
};

компонент входа в приложение , принудительно запрашивающий обновление attributeChangedCallback method.

@customElement('app-login')
export class AppLogin extends LitElement {
    @property({
        type: Object,
    })
    user: UserType | null = null;

    loginSuccessEventKey: string = 'login-success';
    loginFailureEventKey: string = 'login-failure';

    logoutSuccessEventKey: string = 'logout-success';
    logoutFailureEventKey: string = 'logout-failure';

    handleClickGetAuth() {
        const token = jwt.sign(userData, process.env.REACT_APP_JWT_SECRET as Secret);

        localStorage.setItem('token', token);

        const loginSuccessEvent = new CustomEvent(this.loginSuccessEventKey, { composed: true, bubbles: true });
        this.dispatchEvent(loginSuccessEvent);
    }
    handleClickLogout() {
        localStorage.removeItem('token');
        const logoutSuccessEvent = new CustomEvent(this.logoutSuccessEventKey, {
            composed: true,
            bubbles: true,
        });

        this.dispatchEvent(logoutSuccessEvent);
    }
    attributeChangedCallback(name: any, oldVal: any, newVal: any) {
        super.attributeChangedCallback(name, oldVal, newVal);
        this.requestUpdate();
    }

    render() {
        const logoutButton = html`
            <app-button primary color="red" @click="${this.handleClickLogout}">Salir</app-button>
        `;
        const loginButton = html`
            <app-button primary color="blue" @click="${this.handleClickGetAuth}">Acceder</app-button>
        `;

        return html`
            <div>
                ${isObjectEmpty(this.user) ? loginButton : logoutButton}
            </div>
        `;
    }
}

Чтобы установить здесь немного больше контекста, после события login-success приложение, которое упаковывает AppHeader, обновляет состояние приложения, помещая его в контекст userContext.

Почему это? Если attributeChangedCallback срабатывает, это потому, что он обнаруживает изменение атрибута, но запускается любое событие свойства, например hasChanged (в том же определении свойства) или updated.

...