Technologies:
Tolerim
a month ago
The inputs I populated with fetched data are not updating when changed - can you help troubleshoot?

const [lname, setLname] = useState("");
<TextField
fullWidth
label="Last name"
name="lname"
required
value = { `${userDetails.lname}` || "" }
onChange={(e) => setLname(e.target.value)}
/>
value
is constant due to the usage of onChange
.
value
to defaultValue
allowed me to update the value, but the initial value became undefined
.
const [lname, setLname] = useState(userDetails.lname);
<TextField
fullWidth
label="Last name"
name="lname"
required
value = {lname}
onChange={(e) => setLname(e.target.value)}
/>
TextField
being empty.
export default function ProfileDetails() {
const { user } = useContext(UserContext);
const [userDetails, setUserDetails] = useState({});
const { dispatch, isFetching } = useContext(UserContext);
useEffect(() => {
axios
.get("http://localhost:42690/api/users/user-details", {
headers: { Authorization: `Bearer ${user.token}` },
})
.then((res) => {
console.log(res.data.fetchedUser);
setUserDetails(
(prevState) => ( { ...prevState, ...res.data.fetchedUser })
);
})
.catch((err) => {
toast.error("Failure to Load Profile");
});
}, []);
Answers(2)
Vogi
a month ago
Verified Answer
It seems that the issue you are facing is due to the fact that the
value
is constant due to the usage of onChange
. One solution is to use defaultValue
instead of value
, which allows you to update the value but the initial value becomes undefined
. Another solution is to use useState
as shown in your code snippet. However, this resulted in the initial TextField
being empty.
You can try using a combination of both solutions by setting the initial state of your useState
hook to an empty string and then using defaultValue
instead of value
. This should allow you to update the value and also display the initial value correctly. Here's an example:
const [lname, setLname] = useState(userDetails.lname || "");
<TextField
fullWidth
label="Last name"
name="lname"
required
defaultValue={userDetails.lname}
onChange={(e) => setLname(e.target.value)}
/>
I hope this helps! Let me know if you have any other questions.Sources
【React】onChangeで値を取得する方法 - Qiitajavascript - React Material UI TextField onchange handler continue ...Unformatted value (or floatValue) within onChange #264 - Githubjavascript - React: TextField onchange - Stack OverflowHow to set useState const to value of input on changeTextField onChange, only value is passed #83 - GithubTolerim
a month ago
It seems like you are having trouble populating the initial value of a TextField in React. The issue is that you are trying to populate the value before the userDetails state has been initialized. Here are some ways to solve this issue:
1. Wait for userDetails state to be populated before rendering the TextField. You can do this by conditionally rendering the TextField only after userDetails state has been initialized. You can make use of a spinner or a loading component to indicate to the user that the data is being loaded. Here's an example:
const [lname, setLname] = useState("");
{userDetails.lname ? (
<TextField
fullWidth
label="Last name"
name="lname"
required
value={lname}
onChange={(e) => setLname(e.target.value)}
/>
) : (
<Spinner />
)}
In this example, we are only rendering the TextField after userDetails.lname is truthy. Otherwise, we are displaying a Spinner component to indicate that the data is being loaded.
2. Initialize the lname state using userDetails.lname only after userDetails state has been initialized. You can do this by using another effect hook that updates the lname state whenever userDetails state changes. Here's an example:
const [lname, setLname] = useState("");
useEffect(() => {
if (userDetails.lname) {
setLname(userDetails.lname);
}
}, [userDetails.lname]);
In this example, we are initializing the lname state using userDetails.lname only after userDetails state has been initialized. We are achieving this by using an effect hook that updates the lname state whenever userDetails.lname changes.
Either of these approaches should solve your issue. Let me know if you have any other questions!