Чтение around, я вижу, что инициализирующее состояние из реквизита в getInitialState()/constructor может быть анти-шаблоном.Как мне создать экземпляр моего состояния из реквизита?
Каков наилучший способ инициализации состояния от реквизита и управления, чтобы он был последовательным?
Как вы можете видеть ниже, я пытаюсь инициализировать мой компонент «карты», так что я, возможно, likeCount и isLikedByMe состояния инициализирована. Я делаю это так, чтобы у меня появился пользовательский счетчик, и текст кнопки Like изменился, сбросив состояние.
На этом этапе я делаю это в конструкторе, но это неправильный способ сделать это. Как мне это сделать?
import * as React from "react";
import { CardLikeButton } from "./buttons";
export enum CardType {
None = 0,
Text,
Image
}
export interface CardMedia {
text?: string;
imageUrl?: string;
}
export interface CardDetails {
isLikedByMe: boolean;
likeCount: number;
}
export interface CardParams extends React.Props<any> {
cardType: number;
cardId: string;
cardMedia: CardMedia;
cardDetails: CardDetails;
}
export class Card extends React.Component<CardParams, CardDetails> {
state: CardDetails;
constructor(props: CardParams) {
super(props);
console.log("in card constructor");
console.log("card type: " + props.cardType);
this.state = { // setting state from props in getInitialState is not good practice
isLikedByMe: props.cardDetails.isLikedByMe,
likeCount: props.cardDetails.likeCount
};
}
componentWillReceiveProps(nextProps: CardParams) {
this.setState({
isLikedByMe: nextProps.cardDetails.isLikedByMe,
likeCount: nextProps.cardDetails.likeCount
});
}
render() {
console.log("RENDERING CARD");
// console.dir(this.props.cardDetails);
// console.dir(this.props.cardMedia);
// console.dir(this.props.cardType);
if (this.props.cardType === CardType.Text) { // status card
return (
<div className="general-card">
<p>Text card.ID: {this.props.cardId}</p>
<p>{this.props.cardMedia.text}</p>
<CardLikeButton onButClick={this.likeButtonClicked} buttonText={this.state.isLikedByMe ? "Liked" : "Like"} isPressed={this.state.isLikedByMe}/>
<p>Like count: {this.state.likeCount}</p>
</div>
);
} else { //photo card
return (
<div className="general-card">
<p>Image card.ID: {this.props.cardId}</p>
<p> {this.props.cardMedia.text} </p>
<img src={this.props.cardMedia.imageUrl} />
<br/>
<CardLikeButton onButClick={this.likeButtonClicked} buttonText={this.state.isLikedByMe ? "Liked" : "Like"} isPressed={this.state.isLikedByMe}/>
<p>Like count: {this.state.likeCount}</p>
</div>
);
}
}
likeButtonClicked =() => {
console.log('in card => like button clicked!');
var _isLikedByMe = this.state.isLikedByMe;
var _likeCount = this.state.likeCount;
if (_isLikedByMe) {
_likeCount--;
} else {
_likeCount++;
}
_isLikedByMe = !_isLikedByMe;
this.setState({
isLikedByMe: _isLikedByMe,
likeCount: _likeCount
})
}
}
Вот основной список компонентов:
/// <reference path="../../typings/index.d.ts" />
import * as React from "react";
import * as ReactDOM from "react-dom";
import {Card} from "./card";
import {CardParams, CardType, CardMedia, CardDetails} from "./card";
var card1: CardParams = {
cardType: CardType.Image,
cardId: "card1234",
cardDetails: {
isLikedByMe: false,
likeCount: 3
},
cardMedia: {
text: "some test text; badescuga",
imageUrl: "http://www9.gsp.ro/usr/thumbs/thumb_924_x_600/2016/06/19/738742-rkx1568-lucian-sinmartean.jpg"
}
};
var card2: CardParams = {
cardId: "card35335",
cardType: CardType.Text,
cardDetails: {
isLikedByMe: true,
likeCount: 1
},
cardMedia: {
text: "some test 2 text"
}
};
var cards = [card1, card2];
ReactDOM.render(
<div>
{
cards.map((item) => {
return (
<Card key={item.cardId} cardId={item.cardId} cardType={item.cardType} cardDetails={item.cardDetails} cardMedia={item.cardMedia}/>
);
})
}
</div>,
document.getElementById("mainContainer")
);
Вы используете состояние контейнера, как Redux? – Mark
Где исходный реквизит? – omerts
@ Марк нет, я не! я новичок и пытаюсь найти лучшие методы работы с реагированием. Есть ли способ справиться с этим без помощи сокращений? – Alex