I'm trying to keep track of a question and an answer inputted by users, over the lifecycle of a component / feature.
Essentially - There is a random number array produced, which the user then remembers and entered, and the data of what the question was and the input is kept, for 6 inputs.
The code is as below.
function Baseline(props) {
const [Stage, setStage] = React.useState(0) // walkthrough Status
const [time, setTime] = React.useState(false) //timer off, on, or in input stage.
const [question, setQuestion] = React.useState()
const [questions, setQuestions] = React.useState([])
const [answer, setAnswer] = React.useState()
const [answers, setAnswers] = React.useState([])
const [isSubmit, setIsSubmit] = React.useState(false)
// RandomString generates a random string of length n
// var numbers = MakeId(0 + 2 * Stage);
var numbers = 'qSLeD9D0PlSE' + Stage
//qSLeD9D0PlSE
React.useEffect(
() => {
if (answers.length === 6) {
//here you would fire your submit to server
setIsSubmit(true)
}
//this sets the time to wait, being 3 seconds
if (time) {
const timeout = setTimeout(() => {
// console.log(answers);
console.log(questions)
// do anything, this block runs after the timeout has "expired"
// could even set state
setTime('input')
console.log('The timeout was called.')
}, 3000) // timeout expires in 6000 ms
// make sure to clear the timeout on component unmount to avoid memory loss issues
return () => clearTimeout(timeout)
// this callback function runs only on component unmount, not re-renders
}
},
[time],
[answers]
)
function handleOnChange(e) {
setAnswer(e.target.value)
}
function handleClick(e, numbers) {
if (!isSubmit) {
setAnswers([...answers, answer])
setTime(true)
} else {
setTime(false)
}
// setTheArray([, newElement]);
setQuestions([...questions, numbers])
setStage(Stage + 1)
e.preventDefault()
console.log('The link was clicked.')
}
let testInput
if (time == true) {
testInput = (
<React.Fragment>
<div>Stage {Stage}</div>
<div className='underline font-light items-center justify-center'>
Hold the numbers in your head!
</div>
<div className='uppercase bg-white tracking-widest text-center font-bold text-5xl shadow p-4 items-center'>
{numbers}
</div>
</React.Fragment>
)
} else if (time == 'input') {
testInput = (
<React.Fragment>
<div>Stage {Stage}</div>
<div className='font-thin px-2 pb-4 text-lg'>Enter Numbers</div>
<div className='bg-white rounded-lg shadow p-4 items-center justify-center'>
<div className=' items-center '>
<label for='answer' className='sr-only font-thin px-2 pb-4 text-lg'>
Answer
</label>
<input
onChange={handleOnChange}
type='text'
value={answer}
name='answer'
id='answer'
className=' items-center shadow-sm focus:ring-indigo-500 focus:border-indigo-500 block w-full sm:text-sm border-gray-300 rounded-md'
placeholder='Enter Here'
/>
</div>
</div>
</React.Fragment>
)
} else if (isSubmit == true && time == false) {
testInput = (
<React.Fragment>
<p className='text-lg leading-7 text-gray-500 mb-5'>
You have completed the test! here are your answers
</p>
<ul>
{answers.map((item) => (
<li key={item}>{item}</li>
))}
</ul>
</React.Fragment>
)
} else if (time == false) {
testInput = (
<p className='text-lg leading-7 text-gray-500 mb-5'>
You are about to do a small short term memory test. A few letters will flash on your
computer monitor for 3 seconds. Your job is to write down as many letters as you can
remember
</p>
)
}
return (
<Sidebar_Users dashboard={"Progress Map"}>
<div className='py-8 min-h-full container mx-auto '>
<div className='mt-2 mb-8 text-3xl leading-8 font-extrabold tracking-tight text-gray-900 sm:text-4xl sm:leading-10'>
Working Memory Test
</div>
{testInput}
<ButtonBaseline
time={time}
Stage={Stage}
handleClick={handleClick}
isSubmit={isSubmit}
numbers={numbers}
// onSubmit={onSubmit}
/>
</div>
</Sidebar_Users>
)
}
const Sidebar_Users = ({ children }) => (
<div>{children}</div>
)
const ButtonBaseline = () => (
<button
onClick={(e, numbers) => handleClick(e)}
className='bg-blue-500 hover:bg-blue-700shadow-xl font-semibold rounded-full fixed right-8 bottom-20 text-xl px-8 py-3 sm:right-16 sm:bottom-16 text-white sm:text-xl sm:py-3 sm:px-7 flex items-center focus:outline-none'
>
<svg
xmlns='http://www.w3.org/2000/svg'
width='24'
height='24'
viewBox='0 0 24 24'
fill='none'
stroke='currentColor'
strokeWidth='2'
strokeLinecap='round'
strokeLinejoin='round'
className='-ml-1 mr-2 h-5 w-5'
>
<circle cx='12' cy='12' r='10'></circle>
<polygon points='16.24 7.76 14.12 14.12 7.76 16.24 9.88 9.88 16.24 7.76'></polygon>
</svg>
<span>Next Step </span>
</button>
)
ReactDOM.render(<Baseline />, document.querySelector('#root'))
<script crossorigin src="https://unpkg.com/react@17/umd/react.production.min.js"></script>
<script crossorigin src="https://unpkg.com/react-dom@17/umd/react-dom.production.min.js"></script>
<div id="root" />Now I am having trouble keeping the Question (being the numbers variable) tracked against the input variable. It just won't stay in the setState given. I'm not really sure why.
Additionally, I'd prefer to keep a key:value pair in one setState statement, but on using setState({}) instead of [], i.e., array versus dictionary, it won't work.
Where am I making a mistake?
from useState not working - wanting to keep track of two variables
No comments:
Post a Comment