【发布时间】:2021-09-19 19:46:34
【问题描述】:
我是 Reactjs 的初学者,我刚刚开始使用 tinde-card-react 开发具有滑动功能的 Tinder 克隆。
我正在尝试使用 React useState() 更新两个变量,但不能。
主函数内部有 2 个主要组件,一个 TinderCards 组件以及左右滑动和回放按钮。问题是,当我手动刷卡时,变量不会更新,而当我使用按钮刷卡时,情况并非如此。
在当前日志中,我向右滑动卡片两次,并记录了变量alreadyRemoved和people。变量 people 最初是一个包含 3 个对象的数组,因此在第二次滑动后它应该只记录 2 个对象而不是 3 个,而 alreadyRemoved 变量应该更新为丢失的people 变量的元素。
这是我的代码:
import React, { useState, useEffect, useMemo } from 'react';
import './IslamCards.css';
import Cards from 'react-tinder-card';
import database from './firebase';
import hate from "./Cross.png"
import replayb from "./Replay.png"
import love from "./Love.png"
import IconButton from "@material-ui/core/IconButton"
function IslamCards(props) {
let [people, setPeople] = useState([])
useEffect(() => {
database.collection("People").onSnapshot(snapshot => { setPeople(snapshot.docs.map(doc => doc.data())) })
}, [])
let [alreadyRemoved , setalreadyRemoved] = useState([])
let buttonClicked = "not clicked"
// This fixes issues with updating characters state forcing it to use the current state and not the state that was active when the card was created.
let childRefs = useMemo(() => Array(people.length).fill(0).map(() => React.createRef()), [people.length])
let swiped = () => {
if(buttonClicked!=="clicked"){
console.log("swiped but not clicked")
if(people.length){
let cardsLeft = people.filter(person => !alreadyRemoved.includes(person))
if (cardsLeft.length) {
let toBeRemoved = cardsLeft[cardsLeft.length - 1] // Find the card object to be removed
let index = people.map(person => person.name).indexOf(toBeRemoved.name)// Find the index of which to make the reference to
setalreadyRemoved(list => [...list, toBeRemoved])
setPeople(people.filter((_, personIndex) => personIndex !== index))
console.log(people)
console.log(alreadyRemoved)
}
}
buttonClicked="not clicked"
}
}
let swipe = (dir) => {
buttonClicked="clicked"
console.log("clicked but not swiped")
if(people.length){
let cardsLeft = people.filter(person => !alreadyRemoved.includes(person))
if (cardsLeft.length) {
let toBeRemoved = cardsLeft[cardsLeft.length - 1] // Find the card object to be removed
let index = people.map(person => person.name).indexOf(toBeRemoved.name)// Find the index of which to make the reference to
setalreadyRemoved(list => [...list, toBeRemoved])
childRefs[index].current.swipe(dir)
let timer =setTimeout(function () {
setPeople(people.filter((_, personIndex) => personIndex !== index))}
, 1000)
console.log(people)
console.log(alreadyRemoved)
}
// Swipe the card!
}
}
let replay = () => {
let cardsremoved = alreadyRemoved
console.log(cardsremoved)
if (cardsremoved.length) {
let toBeReset = cardsremoved[cardsremoved.length - 1] // Find the card object to be reset
console.log(toBeReset)
setalreadyRemoved(alreadyRemoved.filter((_, personIndex) => personIndex !== (alreadyRemoved.length-1)))
if (!alreadyRemoved.length===0){ alreadyRemoved=[]}
let newPeople = people.concat(toBeReset)
setPeople(newPeople)
// Make sure the next card gets removed next time if this card do not have time to exit the screen
}
}
return (
<div>
<div className="cardContainer">
{people.map((person, index) => {
return (
<Cards ref={childRefs[index]} onSwipe={swiped} className="swipe" key={index} preventSwipe={['up', 'down']}>
<div style={{ backgroundImage: `url(${person.url})` }} className="Cards">
<h3>{person.name}</h3>
</div>
</Cards>);
})}
</div>
<div className="reactionButtons">
<IconButton onClick={() => swipe('left')}>
<img id="hateButton" alt="d" src={hate} style={{ width: "10vh", marginBottom: "5vh", pointerEvents: "all" }} />
</IconButton>
<IconButton onClick={() => replay()}>
<img id="replayButton" alt="e" src={replayb} style={{ width: "11vh", marginBottom: "5vh", pointerEvents: "all" }} />
</IconButton>
<IconButton onClick={() => swipe('right')}>
<img id="loveButton" alt="f" src={love} style={{ width: "11vh", marginBottom: "5vh", pointerEvents: "all" }} />
</IconButton>
</div>
</div>
);
}
export default IslamCards;
我的控制台日志:
更新:
按照第一个答案的建议,我从 swiped() 函数中删除了 Timer,但问题仍然存在。
希望能得到更多的建议,以便解决这个问题。
【问题讨论】:
标签: javascript reactjs firebase react-native