Проблема
Я пытаюсь использовать реактивную пружину, чтобы анимированные буквы из массива входили и выходили для моего приложения Hangman. Я хочу, чтобы они исчезали при загрузке и исчезали при удалении из массива. Они удаляются из массива по клику. Сейчас я просто хочу, чтобы они исчезали и исчезали. Самым близким, что я получил, были те же кнопки, что и раньше, но они были медленными и совсем не анимировались.
Я пытался использовать компоненты Spring, Transition Components и useTransition.
Это самый последний пример, из которого я пытался отработать. codesandbox
APP --- не включает все функции useState или вспомогательные функции для удобства чтения
const App = () => {
const [availableLetters, setAvailableLetters] = useState([
'a',
'b',
'c',
'd',
'e',
'f',
'g',
'h',
'i',
'j',
'k',
'l',
'm',
'n',
'o',
'p',
'q',
'r',
's',
't',
'u',
'v',
'w',
'x',
'y',
'z'
])
const location = useLocation()
const transitions = useTransition(location, location => location.pathname, {
from: { opacity: 0, transform: 'translate(100%,0)' },
enter: { opacity: 1, transform: 'translate(0,0)' },
leave: { opacity: 0, transform: 'translate(-50%,0)' }
})
return (
<Fragment>
<Header defaultGuesses={defaultGuesses} />
{msgAlerts.map((msgAlert, index) => (
<AutoDismissAlert
key={index}
heading={msgAlert.heading}
variant={msgAlert.variant}
message={msgAlert.message}
/>
))}
{/* routes */}
<main className="container">
{transitions.map(({ item, props, key }) => (
<animated.div native='true' key={key} style={props}>
<Switch location={item}>
{/* home */}
<Route
exact
path="/"
render={() => (
<Welcome
msgAlert={msgAlert}
resetAllButSecret={resetAllButSecret}
setSecret={setSecret}
/>
)}
/>
<Route
exact
path="/guesses"
render={() => (
<Guesses
msgAlert={msgAlert}
secret={secret}
setGuesses={setGuesses}
resetAllButSecretAndGuesses={resetAllButSecretAndGuesses}
setDefaultGuesses={setDefaultGuesses}
/>
)}
/>
<Route
exact
path="/play"
render={() => (
<Play
guesses={guesses}
availableLetters={availableLetters}
correctLetters={correctLetters}
incorrectLetters={incorrectLetters}
secret={secret}
setSecret={setSecret}
pushToCorrect={pushToCorrect}
pushToIncorrect={pushToIncorrect}
removeAvailable={removeAvailable}
msgAlert={msgAlert}
resetBoard={resetBoard}
gameOver={gameOver}
setGameOver={setGameOver}
setGuesses={setGuesses}
resetGame={resetGame}
/>
)}
/>
</Switch>
</animated.div>
))}
</main>
</Fragment>
)
}
export default App
Relevant Play. js code. Это то, что я сейчас пытаюсь, но ничего даже не появляется, букв вообще нет
import { Spring, animated, Transition } from 'react-spring/renderprops'
import ClickableLetter from './ClickableLetter'
const AnimatedLetter = animated(ClickableLetter)
const Play = ({'tons of props i'm not showing'}) => {
const availHTML = availableLetters.map((letter, index) => (
<Transition
from={{ opacity: 0 }}
to={{ opacity: 1 }}
leave={{ opacity: 0 }}
// config={config.slow}
key={`${letter}_${index}`}
>
{styles => (
<AnimatedLetter
style={styles}
pushToCorrect={pushToCorrect}
pushToIncorrect={pushToIncorrect}
secret={secret}
removeAvailable={removeAvailable}
letter={letter}
gameOver={gameOver}
msgAlert={msgAlert}
/>
)}
</Transition>
))
return (
<AbsoluteWrapper>
<Fragment>
{availHTML}
</Fragment>
</AbsoluteWrapper>
)
}
Оригинальный рабочий код
const availHtml = availableLetters.map(letter => (
<ClickableLetter
key={letter}
pushToCorrect={pushToCorrect}
pushToIncorrect={pushToIncorrect}
secret={secret}
removeAvailable={removeAvailable}
letter={letter}
gameOver={gameOver}
msgAlert={msgAlert}
/>
))
ClickableLetter. js
import React from 'react'
import { withRouter } from 'react-router-dom'
import { PrimaryButton } from '../Shared/Styled'
// these are the green letters used to let a user guess a letter
const ClickableLetter = ({
letter, secret, pushToCorrect, pushToIncorrect, removeAvailable, gameOver, msgAlert
}) => {
// this function is used to either push the value to a correct or incorrect array causing an app wide state change and re render
const pushValue = () => {
if (!gameOver) {
if (secret.toLowerCase().includes(letter)) {
pushToCorrect(letter)
} else {
pushToIncorrect(letter)
}
// take it from the availLetter arr to re-render this component with one less letter
removeAvailable(letter)
} else {
msgAlert({
heading: 'Oops!',
message: 'Game is over, please click reset to play again',
variant: 'danger'
})
}
}
return (
<PrimaryButton onClick={pushValue}>{letter}</PrimaryButton>
)
}
export default withRouter(ClickableLetter)
Другие попытки
const transitions = useTransition(availableLetters, item => item, {
from: { opacity: 0},
enter: { opacity: 1},
leave: { opacity: 0}
})
const availHTML = transitions.map(({ item, props, key }) =>
<AnimatedLetter key={key} style={props}
pushToCorrect={pushToCorrect}
pushToIncorrect={pushToIncorrect}
secret={secret}
removeAvailable={removeAvailable}
letter={item}
gameOver={gameOver}
msgAlert={msgAlert}/>
)
Другой моей попыткой было использование animated.div вместо animated (ClickableLetter) с ClickableLetter, отображаемым внутри div. Что-то вроде этого. (У меня нет кода, так что это не точно)
const availHTML = transitions.map(({ item, props, key }) =>
<animated.div key={key} style={props}><ClickableButton letter={item}/> </animated.div>
))