const is a signal that the variable won’t be reassigned.
let is a signal that the variable may be reassigned
Additional things to ponder:
- Use
constby default - Use
letonly if rebinding is needed constdoes not indicate that a value is ‘constant’ or immutable.const foo = {}; foo.bar = 10; console.log(foo.bar); // --> 10Only the binding is immutable. ie using an assignment operator or a unary or postfix -- or ++ operator on a const variable throws a TypeError exception
ES6
constandletare hoisted too. Although the identifiers has the same memory reference from compile time, they cannot be accessed before declaration in the code. (but not as we thought the declaration would be physically moved to the top in the scope) ;)
const is a signal that the variable won’t be reassigned.
let is a signal that the variable may be reassigned
Additional things to ponder:
- Use
constby default - Use
letonly if rebinding is needed constdoes not indicate that a value is ‘constant’ or immutable.const foo = {}; foo.bar = 10; console.log(foo.bar); // --> 10Only the binding is immutable. ie using an assignment operator or a unary or postfix -- or ++ operator on a const variable throws a TypeError exception
ES6
constandletare hoisted too. Although the identifiers has the same memory reference from compile time, they cannot be accessed before declaration in the code. (but not as we thought the declaration would be physically moved to the top in the scope) ;)
const vs let is mostly to do with "changing" in a code block. It only matters in situations like this:
const myValues = this.props.someData;
if (*some condition*) {
myValues = [];
}
In this situation you would need to use let because you are changing the value assigned to the variable myValues:
let myValues = this.props.someData;
if (*some condition*) {
myValues = [];
}
If props.someData is changing it will trigger a re-render of the component. So const vs let does not come in to play. The entire render method is re-run.
So that said, I use const in the situations you are describing. Unless you are directly manipulating the valuable of a variable, use const.
How come, we can modify the const variable in react but not in vanilla js ?
Why do we use "const" for useState instead of "let"?
How to define constants in ReactJS - Stack Overflow
reactjs - Simple let or const variables in react - Stack Overflow
Videos
We use const variables in react and can easily modify the value. While same thing in vanilla js throws error. Why ?
Edit: I'm talking about useState hook. sorry, if am not even asking the right question.
Noob question maybe but I was just thinking about this. I found a stackoverflow answer to this question that was along the lines of "When the component is rerendered, the function is executed again, creating a new scope, creating a new state variable"
But components rerender only when the state changes, so that means it's changing the const variable first, and then rerendering the component which creates a new scope?
E.g
function App() {
const [count, setCount] = useState(0)
function handleChange() {
setCount(count + 1)
}
....
}Unless setCount(count + 1) triggers a re-render before the count changes. So is the order:
setCount is fired
component rerenders with new scope
react remembers old count variable
count = old variable + 1
Is that how it works?
You don't need to use anything but plain React and ES6 to achieve what you want. As per Jim's answer, just define the constant in the right place. I like the idea of keeping the constant local to the component if not needed externally. The below is an example of possible usage.
import React from "react";
const sizeToLetterMap = {
small_square: 's',
large_square: 'q',
thumbnail: 't',
small_240: 'm',
small_320: 'n',
medium_640: 'z',
medium_800: 'c',
large_1024: 'b',
large_1600: 'h',
large_2048: 'k',
original: 'o'
};
class PhotoComponent extends React.Component {
constructor(args) {
super(args);
}
photoUrl(image, size_text) {
return (<span>
Image: {image}, Size Letter: {sizeToLetterMap[size_text]}
</span>);
}
render() {
return (
<div className="photo-wrapper">
The url is: {this.photoUrl(this.props.image, this.props.size_text)}
</div>
)
}
}
export default PhotoComponent;
// Call this with <PhotoComponent image="abc.png" size_text="thumbnail" />
// Of course the component must first be imported where used, example:
// import PhotoComponent from "./photo_component.jsx";
If you want to keep the constants in the React component, use statics property, like the example below. Otherwise, use the answer given by @Jim
var MyComponent = React.createClass({
statics: {
sizeToLetterMap: {
small_square: 's',
large_square: 'q',
thumbnail: 't',
small_240: 'm',
small_320: 'n',
medium_640: 'z',
medium_800: 'c',
large_1024: 'b',
large_1600: 'h',
large_2048: 'k',
original: 'o'
},
someOtherStatic: 100
},
photoUrl: function (image, size_text) {
var size = MyComponent.sizeToLetterMap[size_text];
}
Using let or const is perfectly fine. Sometimes you need to declare variables that are derived from props or states, in order to make the code declarative and readable.
Regarding your performance doubt, you can always use useMemo hook to memoize the derived value and avoid calculating it on each render. But this should be avoided as long as your code is not expensive computationally.
export default function MyComponent(props) {
const otherCondition = props.content.length > 20;
const myVariable = useMemo(() => {
let myVariable = 0;
if (props.isDisabled && otherCondition) {
// ...more complex checks...
myVariable = 1;
} else {
myVariable = 2;
}
return myVariable
},
[props.isDisabled, otherCondition])
return (
<>
{/* some JSX */}
</>
);
}
Use of const is preferable if your variable is not getting assigned again, use linters in VS Code and it will let you know where a variable can be const.
Use of let if you wish to make a variable re-assignable. It is less used in practice though. Let us assume a case that you need to use a variable and again re-assign it in a function or a loop, then let should be used.
Regarding hooks then they are of great help, they make us code better and code complex. As you mentioned that hooks do re-renders if data changes, and if there is some changes in DOM element, then only it is assigned to the create.reactElement. Regarding re-renders, you can have a beautiful medium post here.
Is the above example of writing let or const variables in react components good practice?
Regarding this, it is the only practice. Prefer const if your variable is not getting re-assigned, that's the key.
Use of hooks will improve your performance in one way or other as you can do complex work with them instead of writing your own functions, hooks are basically functions that is created at a place and use anywhere. so, you are normally doing function calls and assigning the output to a variable as you do when you call your own functions.
Regarding your example, if you are not re-using otherCondition that don't make a variable out of it, simply use it in your condition like
if (props.isDisabled && props.content.length > 20) { ... }
Why to allocate memory for a single use variable? Other than this, your code looks fine to me.
When you want to define some constant values like style or image URLs then it's always better to define that outside of component. It will become global values and available inside each function/class of that file.
Another option of defining constants is on a class instance itself, but then that variable will be available only inside the class. It means if you defined two classes inside the same file, then one class variable would not be available inside another class.
Like this:
class ABC extends React.Component{
constructor(){
super();
this.a = 10;
this.b = 20;
}
render(){
console.log(this.a, this.b);
return (....);
}
}
Note: React classes don't have the feature of class level properties; we can only define methods. But if you want to define values then you need to use class transform properties.
Create a constants.js for shared constant variables/objects and export it from there for better maintainability.
export const redPanda = {
src: 'https://upload.wikimedia.org/wikipedia/commons/b/b2/Endangered_Red_Panda.jpg',
alt: 'Red Panda',
width: '200px',
};
import React from 'react';
import ReactDOM from 'react-dom';
import { redPanda } from 'path/to/your/constants/file'; //import from your constants.js
class RedPanda extends React.Component {
render() {
return (
<div>
<h1>Cute Red Panda</h1>
<img src={redPanda.src} alt={redPanda.alt} width={redPanda.width} />
</div>
);
}
}
ReactDOM.render(<RedPanda />, document.getElementById('app'));
setState is definitely the right thing to do. That is the React hooks way of having data that, when it changes, causes a re-render.
I have tried const [priceMap, setpriceMap] = useState([]); but it only sets single value to priceMap.
Why are you setting priceMap to an Array when you want it to be an Object? Try something like this:
const CreateNewTab = () => {
const [priceMap, setPriceMap] = useState({});
return (
<Form>
<Form.Item
label="Price Map"
name="priceMap"
rules={[{ required: true, message: "Please input Prices!"}]}
>
{selectedProducts.flatMap(productId => products
.filter(product => product.id === productId)
.map(product => (
<Input.Group compact>
<Form.Item label={product.productName + " : "} />
{product.priceList.map((priceObj) => (
<Form.Item
label={priceObj.type}
key={priceObj.priceId}
>
<Input
defaultValue={priceObj.price}
rules={[{ required: true, message: "Please input price!" }]}
onChange={(changedValues) => {
setPriceMap({
...priceMap,
[priceObj.id]: changedValues[Object.keys(changedValues)[0]]
})
}} />
</Form.Item>
))}
</Input.Group>
))
)}
</Form.Item>
</Form>
);
};
Notice that when you call setPriceMap you pass a new object rather than mutating the object.
A constant is exactly what the name suggests. It will always be constant and immutable. If you change it to let priceMap = {}; you should be able to change its values