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