I am trying to set the state using React hook setState() using the props the component receive. I've tried using the below code:
import React,{useState , useEffect} from 'react'; const Persons = (props) => { // console.log(props.name); const [nameState , setNameState] = useState(props) console.log(nameState.name); console.log(props.name); return ( <div> <p>My name is {props.name} and my age is {props.age}</p> <p>My profession is {props.profession}</p> </div> ) } export default Persons;
The issue is the state is being set upon component being loaded. But when it receive new props, the state is not getting updated. How to update the state in this case? Thanks in advance.
Passing props to state using useState Hooks import React, { useState } from 'react'; const Profile = props => { const [profileState, setProfileState] = useState(props); return ( <div> <p> <strong>Name:</strong> {profileState.name} </p> <p> <strong>Email:</strong> {profileState.
The setState() Method State can be updated in response to event handlers, server responses, or prop changes. This is done using the setState() method. The setState() method enqueues all of the updates made to the component state and instructs React to re-render the component and its children with the updated state.
Since the DetailView then doesn't need any local state at all, we won't have the problem of putting props into state. Now, the App has full control over all the state, and the DetailView is just a so-called "dumb component". This approach is feasible for many use-cases, but it's not without drawbacks.
useState
hooks function argument is being used only once and not everytime the prop changes. You must make use of useEffect
hooks to implement what you would call the componentWillReceiveProps/getDerivedStateFromProps
functionality
import React,{useState , useEffect} from 'react'; const Persons = (props) => { const [nameState , setNameState] = useState(props) useEffect(() => { setNameState(props); }, [props]) return ( <div> <p>My name is {props.name} and my age is {props.age}</p> <p>My profession is {props.profession}</p> </div> ) } export default Persons;
The props
value in useState(props)
is used only during the initial render, further state updates are done with the setter setNameState
.
In addition, there is no need for useEffect
when updating derived state:
const Person = props => { const [nameState, setNameState] = useState(props.name); // update derived state conditionally without useEffect if (props.name !== nameState) setNameState(props.name); // ... other render code };
From React docs:
[...] you can update the state right during rendering. React will re-run the component with updated state immediately after exiting the first render so it wouldn’t be expensive.
[...] an update during rendering is exactly what
getDerivedStateFromProps
has always been like conceptually.
In essence, we can optimize performance by getting rid of an additional browser repaint phase, as useEffect
always runs after the render is committed to the screen.
This is a contrived example illustrating above pattern - in real code you would read props.name
directly. See the React blog post for more appropriate derived state use cases.
const Person = props => { const [nameState, setNameState] = React.useState(props.name); // Here, we update derived state without useEffect if (props.name !== nameState) setNameState(props.name); return ( <p> <h3>Person</h3> <div>{nameState} (from derived state)</div> <div>{props.name} (from props)</div> <p>Note: Derived state is synchronized/contains same value as props.name</p> </p> ); }; const App = () => { const [personName, setPersonName] = React.useState("Lui"); const changeName = () => setPersonName(personName === "Lukas" ? "Lui" : "Lukas"); return ( <div> <Person name={personName} /> <button onClick={changeName}>Change props</button> </div> ); }; ReactDOM.render(<App />, document.getElementById("root"));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.13.0/umd/react.production.min.js" integrity="sha256-32Gmw5rBDXyMjg/73FgpukoTZdMrxuYW7tj8adbN8z4=" crossorigin="anonymous"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.13.0/umd/react-dom.production.min.js" integrity="sha256-bjQ42ac3EN0GqK40pC9gGi/YixvKyZ24qMP/9HiGW7w=" crossorigin="anonymous"></script> <div id="root"></div>
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With