Reputation: 17342
I'm not quite sure where to initiate calculated values in a react component. So this is how I am doing it right now:
render () {
const { foo } = this.props
const { bar } = this.state
const calculatedValue = bar ? foo * bar : foo
return (
<div>{calculatedValue}</div>
)
}
Or should I initiate calculatedValue
in componentDidMount()
Upvotes: 3
Views: 2135
Reputation: 326
This depends on how your calculated value is going to change in your application. If is a value that will not change, your just wanna when the first render of the component (what you probably not), you're fine calculating in componentDidMount
and assigning to a property (this.calculatedValue = ...
) and accessing in render with this.calculatedValue
, but it's not the "React way".
Assuming you're using the state
, something that will be change in your application, then you will need to put your calculation in somewhere else.
Here are some options to you to keep your calculated values:
1. In your render method, just like you did:
Fine for simple calculations, but believe me, this thinks can grow...
render () {
const { foo } = this.props
const { bar } = this.state
const calculatedValue = bar ? foo * bar : foo
return (
<div>{calculatedValue}</div>
)
}
2. In a getter method:
keeping the calculation separated for your render method
getCalculatedValue() {
const { foo } = this.props
const { bar } = this.state
return bar ? foo * bar : foo
}
render () {
return (
<div>{ this.getCalculatedValue() }</div>
)
}
3. [ES6] With a getter property:
Just a variation for the option above, but a little more cleaner since your aren't calling a method, just accessing a property and your function is running "under the table".
get calculatedValue() {
const { foo } = this.props
const { bar } = this.state
return bar ? foo * bar : foo
}
render () {
return (
<div>{ this.getCalculatedValue }</div>
)
}
4. In the parent component, making this one just to show the value:
This one is a little more complex, but usually is better for growing projects. Here we will separate your component in two: The first will calculate (here you can access some API or anywhere your value was coming from) and the child one will just show it's value. This way you can keep the logic and the ui in different components, improving your reuse of code among your project. Is a good pattern to keep your UI components (the child one) in a functional component without state, but this is for another question.
/* A functional component. Is just like a class, but without state */
const MyUIComponent = props => <div>{ props.value }</div>
class MyLogicalComponent extends React.Component {
render(){
/* you can choose any of the options above to calculate */
const computedValue = 5 + 8;
return (
<div>
<MyUIComponent value={ computedValue } />
</div>
)
}
}
Hope it helps!
Upvotes: 2
Reputation: 25937
calculatedValue
is a const variable having block scope in your Render
function. If you need to use its value in Render
function there is no option but to calculate it in Render
function only.
componentDidMount = () => {
const { foo } = this.props
const { bar } = this.state
const calculatedValue = bar ? foo * bar : foo //block scope
}
If you declare the variable calculatedValue
in componentDidMount()
function as shown above then it will not be accessible in Render
function which gets called later in the lifecycle of a reactJs component.
render = () => {
//calculatedValue will give undefined error. calculatedValue is not known to render function
return (
<div>{calculatedValue}</div>
)
}
Upvotes: 0
Reputation: 580
I think it really depends on how much calculation you are doing. For something as simple as your example above I would usually just do that in render()
.
Anything above very basic functionality and I would split it out into a separate function such as getFooBarCalcValue()
.
This way your render method doesn't get too cluttered with things that would otherwise be elsewhere.
Upvotes: 4