Ajit Kumar
Ajit Kumar

Reputation: 73

Child component's input field not changing with change in parent's props react

I have this ParentComponent with a <select> and a ChildComponent with an input field, with its type and value dependent on props received. As it is clear in the code, the parent component's onChangeHandler updates its state and sends it as prop data to child, to which the input field is expected to change.
I can get the input type changed but the input value is not changing, to which I did value={this.state.input} which is forcefully getting updated with componentWillRecieveProps. Now I am getting the state updated (with a price of You got me updated again :/ twice), with no change in input value.

Please let me know what I am missing or where I am wrong, and if there is any better way to achieve this. Thanks in advance.

const ParentComponent = () => {
    const [selectOpt, setSelectOpt] = useState("")
    const onChangeHandler = (e) => {
        setSelectOpt(e.target.value)
    }
    return (
        <select onChange={(e)=>onChangeHandler(e)}>
            <option value="text">text</option>
            <option value="email">email</option>
            <option value="password">password</option>
        </select>
        <ChildComponent data={selectOpt} />
    )
}
class ChildComponent extends Component {
    state = {
        input:this.props.data
    }
    componentDidUpdate() {
        console.log("You got me updated again :/")
    }
    componentWillReceiveProps(nextProps){
        if(nextProps.data !== this.props.data){
            this.setState({ input:nextProps.data })
        }
    }
    render(){
        return( <input type={this.props.data} value={this.state.input} /> )
    }
}

Upvotes: 3

Views: 1192

Answers (2)

AphonopelmaChalcodes
AphonopelmaChalcodes

Reputation: 334

I've been dealing with a similar issue and what helped was setting "key" on a child component. When "key" changes it indicates that component should be refreshed.

You can try this:

<ChildComponent key={selectOpt} data={selectOpt}/>

Upvotes: 3

FireFighter
FireFighter

Reputation: 706

It's bad practice to put props into its own state, so you should try to avoid that. I don't really know what the prop attribute for the type is, so I am just gonna go with type="text":

const ParentComponent = () => {
    const [selectOpt, setSelectOpt] = useState("")
    const onChangeHandler = (e) => {
        setSelectOpt(e.target.value)
    }
    return (
        <select onChange={onChangeHandler}>
            <option value="text">text</option>
            <option value="email">email</option>
            <option value="password">password</option>
        </select>
        <ChildComponent data={selectOpt} />
    )
}
const ChildComponent = ({ data }) => {
    return ( 
        <input type="text" value={data} /> 
    )
}

Upvotes: 1

Related Questions