У меня есть массив «выбранных карт», сохраненный в состоянии «selectedCards», который обновляется в зависимости от того, ссылался ли пользователь на идентификатор «Карты» или нет (с помощью флажка).
КогдаКомпонент монтируется, массив по умолчанию сопоставляется с использованием компонента «Карта» и добавляется в стек.Доступ к ним осуществляется с помощью ссылок и с использованием взаимодействия в стиле трутов, пользователи могут выбрасывать влево или вправо с помощью клавиатуры или перетаскивания из стека.
Когда компонент обновляется и добавляет новые карты в стек, ссылки становятсявернулся как ноль.Почему это так?
export default class Cards extends Component {
constructor(props, context) {
super(props, context);
this.config = {
throwOutDistance: () => Math.max(window.innerWidth, window.innerHeight),
throwOutConfidence: () => 1,
allowedDirections: [
Direction.LEFT,
Direction.RIGHT,
]
};
const fakeEvent = {
target: {
id: 'digiDesign',
}
};
this.cardRefs = new Map();
this.state = {
selectedCategories: ['digiDesign', 'branding'],
selectedCards: this.filterArray(fakeEvent),
cardStack: cardData,
currentCard: cardData.length - 1,
cardIndex: 0,
checked: false,
};
}
componentDidMount() {
const { selectedCards } = this.state;
//Intiates key listener
document.addEventListener("keydown", this.onDirection);
//Configures Swing.js
this.stack = Stack(this.config);
this.stack.on("dragstart", () => this.setState({ dragging: true }));
this.stack.on("dragend", () => this.setState({ dragging: false }));
this.stack.on("throwout", this.onThrowOut.bind(this));
//Config stack of cards
this.createStack();
//Logs initial cards
console.log(selectedCards, 'selected cards')
}
handleChange(e){
const { selectedCards } = this.state;
if (e.target.checked){
for (let i = 0; i < this.filterArray(e).length; i++){
selectedCards.push(this.filterArray(e)[i])
}
} if (!e.target.checked){
this.removeArray(e);
}
this.setState({
selectedCards
})
console.log(selectedCards)
}
createStack(){
const { selectedCards } = this.state;
this.cardRefs.forEach((ref) => {
const el = ReactDOM.findDOMNode(ref);
this.stack.createCard(el);
});
this.setState({
currentCard: selectedCards.length - 1
})
}
destroyStack(){
this.cardRefs.forEach((ref) => {
const el = ReactDOM.findDOMNode(ref);
const card = this.stack.getCard(el);
card.destroy();
});
}
componentWillUnmount() {
this.destroyStack()
}
//Controls keycodes
onDirection = e => {
if(e.keyCode === 37){
this.throwoutLeft();
} if (e.keyCode === 39) {
this.throwoutRight();
}
}
//Controls throwout right with key
throwoutRight(){
const el = ReactDOM.findDOMNode(
this.cardRefs.get(this.state.currentCard)
);
const card = this.stack.getCard(el);
card.throwOut(1000, 0);
}
//Controls throwout left with key
throwoutLeft(){
const el = ReactDOM.findDOMNode(
this.cardRefs.get(this.state.currentCard)
);
const card = this.stack.getCard(el);
card.throwOut(-1000, 0);
}
//Controls swipe/grab
onThrowOut() {
const activeCard = this.state.currentCard
if (activeCard > 0){
this.setState({
currentCard: activeCard - 1
})
}
if (activeCard === 0){
this.setState({
currentCard: activeCard - 1
})
this.resetDeck();
}
}
//Resets the deck on finish
resetDeck() {
const { selectedCards } = this.state
this.setState({
currentCard:selectedCards.length - 1,
resetting: true
});
this.createStack()
this.setState({
resetting: false,
});
}
//Controls checkboxes
filterArray(e){
let filteredArray = cardData.filter(function(x){
return x.id === e.target.id
});
return filteredArray
}
removeArray(e){
const{ selectedCards } = this.state;
for (let i = selectedCards.length-1; i >= 0; i--){
if(selectedCards[i].id === e.target.id){
selectedCards.splice(i, 1)
}
}
}
render() {
const { selectedCards } = this.state;
return (
<div className='container'>
<Viewport>
<CardStack className='stack'>
{selectedCards.map((card, i) => {
return (
<Card
selectedCategories={this.state.selectedCategories}
key={card.advice}
ref={c => this.cardRefs.set(i, c)}
advice={card.advice}
id={card.id}
tag={card.tag}
isSelected={this.state.selectedCategories.indexOf(card.id) > -1}
active={i === this.state.currentCard}
next={i === this.state.currentCard - 1}
previous={i > this.state.currentCard}
dragging={
(i === this.state.currentCard && this.state.dragging) ||
this.state.resetting
}
/>
)
})}
</CardStack>
<FilterContainer>
{
filterData.map((item, i) => {
const active = i === 0;
return (
<Filters
ref='input'
key={item.id}
id={item.id}
label={item.label}
onChange={(e) => this.handleChange(e)}
active={active}
/>
)
})
}
</FilterContainer>
</Viewport>
</div>
);
}
}
Ожидаемый результат - новые карты получат функцию throwIn, но, если новые реферы возвращаются как ноль, этого достичь нельзя.