Reputation: 73
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
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
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