Я создаю приложение с 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
теряет свою ценность, но я не уверен, как это проверить.