Компонент переопределяется только в том случае, если троичное выражение находится непосредственно внутри метода render (). - PullRequest
0 голосов
/ 14 октября 2018

Я создаю приложение с React, Redux и TypeScript.

В верхней панели навигации у меня есть ссылка «Войти», которая при нажатии отправляет действие.На данный момент все это действие устанавливает логическое значение auth в значение true.

У меня есть много подключенных компонентов, которые прослушивают это свойство auth хранилища редуксов и решают, какие подкомпоненты отображать, основываясь на троичных выражениях, которые оценивают this.props.auth.

Я был удивлен, увидев, что, когда я нажал «Войти», некоторые компоненты переставили бы, как ожидалось, в то время как у других было бы успешно изменено их состояние, но изменили бы их отображение, только если я обновил страницу или перенаправил и вернулся,После нескольких часов стрижки волос, я полагаю, что, наконец, изолировал разницу между двумя видами компонентов, описанными выше: если троичное выражение, которое оценивает this.props.auth, находится непосредственно внутри метода render(), компонент ведет себя, как и ожидалось, однако, еслитроичное выражение находится внутри функции .map(), которая затем вызывается методом render(), затем происходит это странное поведение, когда мне нужно обновить, чтобы корректный рендеринг соответствовал значениям проп.В чем дело?this теряет свою ценность, это проблема синхронизации / асинхронности?

class LatestArticles extends Component<LatestArticlesProps> {

public latestArticlesList: JSX.Element[] = Articles.map((a: IArticle) => {
    return (
        <React.Fragment key={a.id}>
            // some TSX

                        {this.props.auth === true ? <UserImgOverlay /> : <UnlockButton />}

            // some more TSX
        </React.Fragment>
    )
});

public render(): JSX.Element {
    return (
        <React.Fragment>
            // some TSX

                    {this.latestArticles}

            // some more TSX
        </React.Fragment>
    )
}

Дайте мне знать, если вам нужно больше контекста, но я хотел бы попросить помощи, чтобы понять, что происходит.Почему изменение реквизита запускает повторное рендеринг только в том случае, если троичное выражение находится непосредственно внутри метода render() и есть ли способ обойти это, все еще отображая данные?Спасибо за ваше внимание.

РЕДАКТИРОВАТЬ

Вот мой mapStateToProps:

// Components/Navbar/index.tsx

const mapStateToProps = ({ articles, auth }: IApplicationState) => {
    return {
        articlesPerPage: articles.articlesPerPage,
        articlesPerPageStep: articles.articlesPerPageStep,
        auth: auth.auth
    }
}

У меня фактически есть другой пример такого поведения, происходящего сметод onClick:

class LatestArticles extends Component<LatestArticlesProps> {

    public latestArticlesList: JSX.Element[] = Articles.map((a: IArticle) => {
        return (
            <React.Fragment key={a.id}>
                // some TSX

                            <StarsRating rating={3} onClick={this.handleRatingClick} />

                // some more TSX
            </React.Fragment>
        )
    });

    constructor(props: LatestArticlesProps & IOwnProps) {
        super(props)

        this.handleRatingClick = this.handleRatingClick.bind(this);
    }

    public render(): JSX.Element {
        return (
            <React.Fragment>
                // some TSX

                        {this.latestArticles}

                // some more TSX
            </React.Fragment>
        )
    }

    public handleRatingClick = () => {
        alert('Clicked!')
    }
}

^ Когда я нажимаю на звезду, ничего не происходит, но если я извлекаю <StarsRating rating={3} onClick={this.handleRatingClick} /> из функции .map и помещаю его непосредственно в метод render (), я получаю предупреждениеговоря "нажал!" ... я подозреваю, что this теряет свою ценность, но я не уверен, как это проверить.

1 Ответ

0 голосов
/ 19 октября 2018

Я думаю, что проблема с переменной latestArticlesList.Инициализируется слишком рано.Это должна быть функция:

public latestArticlesList: JSX.Element[] = () => Articles.map((a: IArticle) => {

Я предполагаю, что Articles должно быть this.props.articlesPerPage.

И, наконец, когда вы используете его, назовите его:

<React.Fragment>
  // some TSX

  {this.latestArticles()}

  // some more TSX
</React.Fragment>
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...