I feel like I am missing the obvious but I can't seem to find another posts that addresses the issue I am having. I am trying to allow an end user the ability to set a location for an object but either entering the information into a form or by clicking a location on a map. I have a react page with three components.
- A Parent container component that holds the other two components.
import {useState} from 'react';
import Box from '@mui/material/Box';
import ObjSetLocationForm from './ObjSetLocationForm';
import ObjSetLocationMap from './ObjSetLocationMap';
export default function LoadSetLocationSet( props ) {
const [prevLat, setPrevLat] = useState("43.5666694");
const [prevLng, setPrevLng] = useState("-101.0716746");
const [newLat, setNewLat] = useState();
const [newLng, setNewLng] = useState();
function setCoords(coords){
setNewLat(coords.lat);
setNewLng(coords.lng);
}
return(
<Box>
<ObjSetLocationForm prevLat={prevLat} prevLng={prevLng} newLat={newLat} newLng={newLng} setCoordsFx={setCoords} />
<ObjSetLocationMap prevLat={prevLat} prevLng={prevLng} newLat={newLat} newLng={newLng} setCoordsFx={setCoords} />
</Box>
);
}
- A Map component that shows a single point on a map A and allows the end user to click on the map to set the point to a new location (lat/lng) and is a child of the Parent container. I will not post all the code to this component because it is pretty big but the important part is that when a user clicks on the map the new lat/lng values are passed back up to the parent component by calling the setCoords function like so.
props.setCoordsFx({lat: e.lngLat.lat, lng: e.lngLat.lng});
I have verified that this is working correctly and is passing the values correctly.
- A Form component that is the second child of the parent container and allows the end user to enter a Lat/Lng to change the position of the single point on the map. This component is where I am having issues. I have two MUI TextFields in an html form that I want to set to the lat/lng values when the user clicks on the map. When I run through the debugger I can see the values getting passed down to this component from the parent and I can even see that the state values that control the components are getting set but the TextFields values never change.
import {useState, useEffect, useContext} from 'react';
import Box from '@mui/material/Box';
import Stack from '@mui/material/Stack';
import Typography from '@mui/material/Typography';
import Button from '@mui/material/Button';
import TextField from '@mui/material/TextField';
export default function LoadSetLocationSet( props ) {
const [newLat, setNewLat] = useState(props.newLat);
const [newLng, setNewLng] = useState(props.newLng);
function handleSubmit(e) {
e.preventDefault();
// Save values to DB.
}
return(
<Box>
<form id="SelLocationForm" onSubmit={handleSubmit}>
<Box sx={{textAlign:'center'}}>
<Typography variant="h6" sx={{display:'inline'}}>Current Location</Typography>
<Box sx={{display:'flex', alignItems:'center', justifyContent:'center'}}>
<Stack direction="row" spacing={3}>
<Box>
<Box>
<Typography>Latitude</Typography>
</Box>
<Box>
<Typography>{props.prevLat}</Typography>
</Box>
</Box>
<Box>
<Box>
<Typography>Longitude</Typography>
</Box>
<Box>
<Typography>{props.prevLng}</Typography>
</Box>
</Box>
</Stack>
</Box>
</Box>
<Box sx={{textAlign:'center', pt:2}}>
<Typography variant="h6" sx={{mb:2}}>Enter the Latitude and Longitude or click the new location on the map</Typography>
<Typography variant="h6" sx={{display:'inline'}}>New Location</Typography>
<Box sx={{display:'flex', alignItems:'center', justifyContent:'center'}}>
<Stack direction="row" spacing={3}>
<Box>
<TextField
id="tbLatitude"
label="Latitude"
type="text"
size="small"
value={newLat}
onChange={(e) => {setNewLat(e.target.value);}}
/>
</Box>
<Box>
<TextField
id="tbLongitude"
label="Longitude"
type="text"
size="small"
value={newLng}
onChange={(e) => {setNewLng(e.target.value);}}
/>
</Box>
<Box sx={{display:'flex', alignItems:'center', justifyItems:'center'}}>
<Button variant="contained" type="submit">Set</Button>
</Box>
</Stack>
</Box>
</Box>
</form>
</Box>
);
}
As you can see I am attempting to use controlled TextFields. So here are my questions/problems:
If setting the default value to a prop value is "anti pattern" how am I supposed to set the default value for form fields if they are a controlled form field?
As I stated earlier when the user clicks on a location on the map it should refresh the form child component and set the values for my controlled form fields to the values passed in but this is not working. How can I accomplish this?
I thought I understood things as I have been doing react for a little bit now but I seem to be lost. Sorry for the newbie question.