Home > Back-end >  How can I update a setState from a parent using a child?
How can I update a setState from a parent using a child?

Time:07-22

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;

CodePudding user response:

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;

CodePudding user response:

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

  • Related