I have an array that its values convert to buttons. When clicked over each of the buttons, its value is written in the ul list. And when click over 'Pop', the last value is remove.
expected output:
I use from useStack hook to implement it. But after running, the output is a blank page and I receive this error in the console:
Uncaught TypeError: stack is undefined
components.js:
import React from 'react';
import {useStack} from './hooks'
export function Demo() {
return (
<div className="demo">
<StackDemo/>
</div>
);
}
const words = ['Apple', 'Banana', 'Cherry', 'Grape'];
function StackDemo() {
const {stack, push, pop} = useStack();
return (<div>
{words.map((word, index) => <button key={index} onClick={() => push(word)}>{word}</button>)}
<button onClick={pop}>» Pop</button>
<ul>
{stack.map((item, index) => <li key={index}>{item}</li>)}
</ul>
</div>);
}
hooks.js:
import {useState} from 'react';
export function useStack() {
const [array,setArray] = useState([]);
const add = (value) => {
return setArray(array.push(value));
}
const del = () => {
return setArray(array.pop());
}
return {array, add, del};
}
Of course, if I edit components.js:
// const {stack, push, pop} = useStack(); to // const [stack, push, pop] = useStack();
And edit hooks.js:
// return {array, add, del} to // return [array, add, del]
But when I click on one of them, output will become blank page, and I receive this error in the console:
Uncaught TypeError: stack.map is not a function
What is the problem? How should I assign useStack output to const {stack, push, pop} ??
Thanks for any help.
CodePudding user response:
There are several issues with the useStack
hook:
- Your
add
function:
const add = (value) => {
return setArray(array.push(value));
}
array.push
returns a number (the new array's length), not the array after the addition of the new element. This causes the white page (caused by a JavaScript TypeError
, because now stack
is not an array anymore).
To fix this, I'd suggest:
const add = (value) => {
return setArray(array.concat(value));
}
- Your
del
function:
const del = () => {
return setArray(array.pop());
}
In this case, array.pop
returns the value that was just popped, so now stack is a string instead of an array.
To fix this, I'd suggest:
const del = () => {
return setArray(array.slice(1));
}
Here's a working example: https://codesandbox.io/s/brave-neumann-41ltx?file=/src/App.js.