Reputation: 2768
I have the following React component which is working as desired. After reading about fully controlled components in this blog post I'm wondering if this code could be refactored to make it fully controlled, which could eliminate the use of getDerivedStateFromProps
, if I understand correctly. Being more familiar with Vue Native than React Native I'm looking for some guidance on how to go about doing such a refactor.
import React, { Component } from "react";
import { Container, Content, Picker } from "native-base";
export default class DynamicPicker extends Component {
constructor(props) {
super(props);
this.state = {
selected: this.props.selected
}
}
static getDerivedStateFromProps(nextProps, prevState) {
if (nextProps.selected !== prevState.selected) {
return ({ selected: nextProps.selected });
} else {
return null;
}
}
onValueChange(value) {
this.setState({
selected: value
});
this.props.onValueChange(value);
}
itemsList = () => {
return (this.props.items.map( (item, index) => {
return (<Picker.Item label={item} key={index} value={item} />)
}));
}
render() {
return (
<Container>
<Content>
<Picker
// note
mode="dropdown"
style={{ borderColor: 'gray', borderWidth: 1, height: 40, margin: 5 }}
selectedValue={this.state.selected}
onValueChange={this.onValueChange.bind(this)}
>
{ this.itemsList() }
</Picker>
</Content>
</Container>
);
}
}
Upvotes: 0
Views: 116
Reputation: 256
From what I'm seeing you actually don't need any state here or the method onValueChange
.
Why do you want to get a value from props just to set it on the state? Can't you just use the selected
value received as props?
Also, can't you just use the method onValueChange
received from props? I don't see any need to make another one in this component, because you're setting a new state, but you're going to change the state after that because you call this.props.onValueChange
. When any prop changes the component will rerender, therefore getDerivedStateFromProps
will be called and it will modify the state.
Long story short, this is how I see this component:
import React, { Component } from "react";
import { Container, Content, Picker } from "native-base";
export default class DynamicPicker extends Component {
itemsList = () =>
// Implicit return from the arrow function
this.props.items.map( (item, index) => {
return (<Picker.Item label={item} key={index} value={item} />)
});
}
render() {
return (
<Container>
<Content>
<Picker
// note
mode="dropdown"
style={{ borderColor: 'gray', borderWidth: 1, height: 40, margin: 5 }}
selectedValue={this.props.selected}
onValueChange={this.props.onValueChange}
>
{ this.itemsList() }
</Picker>
</Content>
</Container>
);
}
}
Upvotes: 1