Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

TextField default value from parent not rendering on child

I'm working on a form with Reactjs that gets some defaultValues from the parent component.

The problem is, the parent component set states of the values with a axios post and pass those values to the child as props. I can print those values on the child component with console.log but if I try to put those values on defaultValues on the TextFields I got a empty form, none of the values is rendered on the form.

Parent component:

export default class Parent extends Component {
   constructor(props){
      super(props);
      this.state={
         somevalue: '',
      }
   }

   componentDidMount(){
      this.getData();
   }

   getData = async () => {
      await api.post('/getValue')
      .then((res) => {
         this.setState({
            someValue: res.data;
         })
      }).catch((err) => {
         console.log("Error: ", err);
      })
   }

   render(){
      return(
         <Child value={this.state.someValue}/>
      )}
}

Child component

export default function Child(props) {
   console.log(props.value); // THIS LOG PRINT THE VALUE PROPERLY
   return(
      <TextField defaultValue={props.value}/>
   )
}

This is basically my code structure, but it's not working. TextField still empty after this.

like image 446
kvym Avatar asked Aug 21 '19 14:08

kvym


1 Answers

The property defaultValue is only used on the initial render. If you'll inspect your code you'll see that before the console.log outputs the value it will first output undefined. You can either change it to a controlled component by changing defaultValue to value. This way the value will display, but you'll need to add an onChange handler for the changes to the value.

function Child(props) {
    // Using the value prop your value will display, but you will also have to pass an onChange handler to update the state in the parent
    return <TextField value={props.value} />;
}

Or you can wait until the value is available before rendering your component

const { someValue } = this.state;
if (!someValue) {
  return "loading the data";
}
return <Child value={someValue} />;

It depends on the exact situation what solution will be better. But I think it's likely you'll want to update the value in the input and do something with it, so I would go with the first situation.

like image 145
Jap Mul Avatar answered Nov 12 '22 03:11

Jap Mul