0

I'm learning React and trying to understand the concept of props and useState Hook working together.

My goal was to make a simple counter and I started with the increase function of it, but I'm getting anywhere.

App.js

import Increase from "./components/Increase";
import { useState } from "react";
import "./App.css";

function App() {
  const [count, setCount] = useState("0");

  return (
    <div>a
      <p>Counter</p>
      <p>{count}</p>
      <Increase onIncrease={(count) => setCount(count)} />
    </div>
  );
}

export default App;

Increase.js

const Increase = (props) => {
  const increaseHandler = (setCount) => {
    setCount((props.count = props.count + 1));
  };

  return <button onClick={increaseHandler}>+</button>;
};

export default Increase;
guilhermxlopes
  • 138
  • 1
  • 7

2 Answers2

2

There are several ways

First, give a function that makes every state manipulation as props

function App() {
  const [count, setCount] = React.useState(0);

  return (
    <div>
      <p>Counter</p>
      <p>{count}</p>
      <Increase onIncrease={()=>setCount(count+1)}/>
    </div>
  );
}

const Increase = ({onIncrease}) => {
  return <button onClick={()=>onIncrease()}>+</button>;
};

ReactDOM.render( < App / > , document.getElementById("root"));
<script crossorigin src="https://unpkg.com/react@16/umd/react.development.js"></script>
<script crossorigin src="https://unpkg.com/react-dom@16/umd/react-dom.development.js"></script>
<div id="root"></div>

Second, only give the setter of state as props

function App() {
  const [count, setCount] = React.useState(0);

  return (
    <div>
      <p>Counter</p>
      <p>{count}</p>
      <Increase setCount={setCount}/>
    </div>
  );
}

const Increase = ({setCount}) => {
  return <button onClick={()=>setCount(count => count +1)}>+</button>;
};

ReactDOM.render( < App / > , document.getElementById("root"));
<script crossorigin src="https://unpkg.com/react@16/umd/react.development.js"></script>
<script crossorigin src="https://unpkg.com/react-dom@16/umd/react-dom.development.js"></script>
<div id="root"></div>
Your problems were :
// First, in app
<Increase onIncrease={(count) => setCount(count)} />

// Second, in increase
const increaseHandler = (setCount) => {
  setCount((props.count = props.count + 1));
};

First, take note that you give as props a function that takes a count as argument and setCount accordingly. It can work if you do :

function App() {
  const [count, setCount] = React.useState(0);

  return (
    <div>
      <p>Counter</p>
      <p>{count}</p>
      {/*You have to give 2 arguments which is not optimal*/}
      <Increase onIncrease={count => setCount(count)} count={count}/>
    </div>
  );
}

const Increase = ({onIncrease, count}) => {
  return <button onClick={()=>onIncrease(count +1)}>+</button>;
};

ReactDOM.render( < App / > , document.getElementById("root"));
<script crossorigin src="https://unpkg.com/react@16/umd/react.development.js"></script>
<script crossorigin src="https://unpkg.com/react-dom@16/umd/react-dom.development.js"></script>
<div id="root"></div>

And second, note that increaseHandler takes a callback as props and fires it with an argument that Increase.js does not have : count, which is undefined in this context

JeanJacquesGourdin
  • 1,496
  • 5
  • 25
2

Here is your solution just added increase handler in parent file (App.js) because parent can manage counter state.

App.js

import Increase from "./components/Increase";
import { useState } from "react";
import "./App.css";

export default function App() {
  const [count, setCount] = useState(0);
  const increaseHandler = () => {
    setCount(count + 1);
  };
  return (
    <div>
      a<p>Counter</p>
      <p>{count}</p>
      <Increase onIncrease={increaseHandler} />
    </div>
  );
}

Increase.js

const Increase = (props) => {
  const { onIncrease } = props;
  return <button onClick={() => onIncrease()}>+</button>;
};

export default Increase;
Umar Ijaz
  • 121
  • 4
  • What's the `const { onIncrease} = props`? Are you receiving an attribute? – guilhermxlopes Jul 21 '22 at 23:31
  • 1
    Well, According to **ES6**, I **destructuring** props. It's similar if we can write **const onIncrease = props.onIncrease** Further more you can read destructuring concept from this link https://medium.com/@lcriswell/destructuring-props-in-react-b1c295005ce0 – Umar Ijaz Jul 22 '22 at 06:29