How to set defaultProp value based on value of other prop?
Using a function component you can do it like this:
function MyComponent({
trigger,
delay: trigger === 'hover' ? 100 : 0,
}) {
return <div>...</div>
}
MyComponent.propTypes = {
trigger: PropTypes.string.isRequired,
delay: PropTypes.number.isRequired,
};
You can do it inside the render method.
render() {
const delay = this.props.trigger === 'hover' ? 100 : 0;
// Your other props
return (
<SomeComponent delay={delay} />
// or
<div>
{/*...something else, use your delay */}
</div>
);
}
I was facing a similar issue and I found a method
based solution missing in this discussion therefore i am writing this answer
There are two cases when you might want to pass default props
Case 1: when you want to choose defaultProps based on a Static value
Case 2: when you want to choose defaultProps based on a Method
Solution for Case 1
class Shape extends Component{
static defaultProps = {
colour: 'red',
}
render(){
const {colour} = this.props;
// Colour will always be 'red' if the parent does not pass it as a prop
return <p>{colour}</p>;
}
}
solution for Case 2
class Shape extends Component{
calcArea = () => {
console.log("Area is x");
}
render(){
const {calcArea} = this.props;
// calcArea will be evaluated from props then from the class method
return <button onClick={calcArea || this.caclArea}></button>;
}
}
I'd rather suggest you to:
- store that variable as an instance variable in the component's class
- evaluate if it is a state variable rather than a prop (or instance)
By the way in both cases you should check when new props arrive to the component and update it if needed.
I'd go for the state variable and write something like this:
class MyComponent extends React.Component {
static propTypes = {
trigger: PropTypes.string,
}
static defaultProps = {
trigger: 'hover',
}
constructor(props) {
super(props);
this.state = {
delay: this.computeDelay(),
}
}
componentWillReceiveProps(nextProps) {
const { trigger: oldTrigger } = this.props;
const { trigger } = nextProps;
if (trigger !== oldTrigger) {
this.setState({
delay: this.computeDelay(),
})
}
}
computeDelay() {
const { trigger } = this.props;
return trigger === 'hover' ? 100 : 0;
}
render() {
...
}
}
In this way you can use this.state.delay
in the render method without taking care of determining its value.