Dima Kruhlyi
Dima Kruhlyi

Reputation: 59

useState doesn't update the state with component

I' trying to create simple counter app on React.js. My code is shown below:

Counter page

import React, { useState } from 'react';
import {Button} from '../components/Button/Button';

export const CounterPage = () => {
    const [counter, setCounter ] = useState(0);
    return (
        <>
            <div className="container" style = {{textAlign : 'center'}}>
                <h2>Counter Page</h2>
                <h3>{counter}</h3>
                <Button onClick = {() => setCounter(0)} value = 'reset' />
                <Button onClick = {() => setCounter(counter - 1)} value = '-'/>
                <Button onClick = {() => setCounter(counter + 1)}  value = '+'/> 
            </div>
        </>
    )
}

Button component

import React from 'react';
import styles from './Button.module.css';
export const Button = (props) => {
    return (
        <button 
            className = {props.value === '+' ? styles.addButton : styles.subButton} 
            type = "button"
        >{props.value}</button>
    )
}

I use useState hook for updating the state, but it doesn't update it. But if I use just

 <button onClick = {() => setCounter(0)}>reset</button>
  <button onClick = {() => setCounter(counter - 1)}>-</button>
  <button onClick = {() => setCounter(counter + 1)}>+</button>

instead of

<Button onClick = {() => setCounter(0)} value = 'reset' />
  <Button onClick = {() => setCounter(counter - 1)} value = '-'/>
  <Button onClick = {() => setCounter(counter + 1)}  value = '+'/>

it works. Could you explain please why? Thanks in advance.

Upvotes: 0

Views: 71

Answers (2)

Kalhan.Toress
Kalhan.Toress

Reputation: 21901

Another clean way you can use is spread the props and add to the button, this way your Button component is more configurable.

EX:

.....
<Button onClick = {() => setCounter(0)} className={styles.addButton}  />
<Button onClick = {() => setCounter(counter - 1)} className={styles.subButton} />
....

and in Button component

export const Button = ({value, ...buttonProps}) => {
    return (
        <button 
            {...buttonProps}, // here use the spread operator
            type = "button"
        >{value}</button>
    )
}

example here

Upvotes: 2

rpie3
rpie3

Reputation: 146

Since you've made your own component, your <Button> component needs to accept a prop of onClick as well:

import React from 'react';
import styles from './Button.module.css';
export const Button = (props) => {
    return (
        <button 
            className = {props.value === '+' ? styles.addButton : styles.subButton} 
            type = "button"
            onClick={props.onClick}
        >{props.value}</button>
    )
}

As it stands, in your second block of code, the onClick is not tied to anything... It's simply a prop that never gets utilized, which is why it's not working. The way you are using useState and setCounter is all done correctly.

Upvotes: 4

Related Questions