skip to Main Content

I need help with managing react states, I can’t seem to wrap my head around it.

I have a component that receives the id of a database entry from another page via useLocation, I then use that id with an axios get request to pull the rest of the data into an array. However, when I am trying to use the data from the get request as a defaultValue for an MUI TextField it doesn’t render the data naturally, the states returns as undefined after the page loads. I have to set the TextField’s key to the get request data (a work around I found in the web) to render. Then when I try to submit the form, the value from the Textfield displays as undefined though the Texfield contains the data from the get request.

const location = useLocation();
const [info, setInfo] = useState([]);

useEffect(()=>{
  axios
    .get("//localhost:3001/Info/" + location.state.id)
    .then((response)=>{
      setInfo(response.data);
  })
});

const validationSchema = Yup.object().shape({});

const formik = useFormik({
  initialValues: {
    name: info.name
  },
  validationSchema: validationSchema,
  onSubmit: (values) => {
    console.log(values) // displays {name: undefined, .....}
  }
});

return(
  <>
    <Container>
      <form onSubmit = {formik.handeSubmit}>
        <TextField
          id = "name"
          label = "Name"
          name = "name"
          onChange = {formik.handleChange}
          onBlur = {formik.handleBlur}
          key = {info.name} //Textfield blank without setting key
          defaultValue = {info.name}
        />
        <Button type = "Submit"> Submit </Button>
      </form>
    </Container>
  </>
);

I am expecting the TextFields default values to render correctly without declaring a key as a work around. Also, I expect the values of the textfields to contain the initialvalues from the formik declaration on submit.

2

Answers


  1. There are few problems in your code, Please do the following fixes:

    1. useEffect is called without dependencies

    Update your useEffect as follows so that it gets triggered only on initial mount:

    useEffect(()=>{
      axios
        .get("//localhost:3001/Info/" + location.state.id)
        .then((response)=>{
          setInfo(response.data);
      })
    }, []);
    
    1. Check if the property name exists before rendering:

      if(!info.name){
        return <div>Loading</div>
      }
      
      return(
        <>
          <Container>
            <form onSubmit = {formik.handeSubmit}>
              <TextField
                id = "name"
             label = "Name"
             name = "name"
             onChange = {formik.handleChange}
             onBlur = {formik.handleBlur}
             key = {info.name} //Textfield blank without setting key
             defaultValue = {info.name}
           />
           <Button type = "Submit"> Submit </Button>
         </form>
       </Container>
       </>
       );
      
    2. Change the initialisation of info. Make it an object since you are expecting an object from api. As:

      const [info, setInfo] = useState({});
      
    Login or Signup to reply.
  2. there are one problem in your code

    useEffect(()=>{
      axios
        .get("//localhost:3001/Info/" + location.state.id)
        .then((response)=>{
          setInfo([...response.data]);
      })
    }, []);
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search