Javascript Unexpected use of comma operator no-sequences warning - javascript

I have a react library which throw following warning.
Unexpected use of comma operator no-sequences
It indicates the warning happens at 5 row, after (_react.Component) parameter.
exports.default = function (_ref) {
return function () {
var _class, _temp2;
return _temp2 = _class = function () {
}(_react.Component),
_class?.displayName = 'Resizable()', _temp2;
};
}
I simplfied the method. It's actually very long function.
How can i fix the warning? What is the proper syntax?

return a <div> tag to the rendered component e.g;
const App=()=>{ return(<div>
<Header/> <Body/>
</div>
);
}
ReactDom.render(<App/>,document.getElementByid("root));

Related

Webpack plugin parser hook doesn't tap for expression

I'm writing a plugin for webpack for extracting values from MyObject.myProperty = 'myValue'; expressions, and my hook doesn't tap for my expression. Here is the example code:
var zzz = (function () {
function zzz() {
return this;
}
zzz.MY_VAR = "My value";
return zzz;
});
Here is how my code for the hook looks like:
parser.hooks.expression.for("zzz.MY_VAR").tap("MyPlugin", expr => {
console.log(expr);
}
I also tried:
parser.hooks.evaluate.for("AssignmentExpression").tap("MyPlugin", expr => {
console.log(expr);
}
Also without success.
I did some debugging, and find out that for some reason when JavascriptParser is calling getFreeInfoFromVariable() in getMemberExpressionInfo() it returns undefined. Because getVariableInfo() method return some scope details instead of VariableInfo instance or 'string'.
Am I missing something ? Is it possible to get value of the object's property via parser somehow ? Or maybe there is another way to do it ?

What determines when a JavaScript ES6 arrow function ends? [duplicate]

This question already has answers here:
What are the rules for JavaScript's automatic semicolon insertion (ASI)?
(7 answers)
Closed 4 years ago.
I realize that an arrow function body can be contained by brackets, but when it doesn't have brackets, what determines when the function terminates?
I'm not sure if this question is general for ES6 or if it is specific to ReactJS or JSX, but I have the following function in React, and right below it, I have the start of a class declaration, which is not within the scope of the function:
const Search = ({ value, onChange, children }) =>
<form>
{children} <input
type="text"
value={value}
onChange={onChange}
/>
</form>
class Table extends Component {
...
...
...
This appears to be valid. What is it about the function that makes it not include the class declaration? Is it that there is a blank line between them? Is it something specific to JSX? Is it because there is a single container element as the body of the function? Or is it something else?
You can enclose your arrow functions with {}
const doSomething = () => {
// ...
return 'val'; // return statement is optional
}
If your arrow functions have only one line of code, it is implicitly understood that it is a return statement and you don't have to wrap them in {}
For example, both these functions are the same.
// explicit return
const doSomething = () => {
return 'val';
}
// implicit return
const doSomething = () => ('val')
You can write implicit return in a few different ways
// implicit return with ()
const doSomething = () => ('val')
// implicit return without ()
const doSomething = () => 'val'
// implicit return in next line with ()
const doSomething = () =>
('val')
// implicit return in next line without ()
const doSomething = () =>
'val'
This is what React does. Top level <tag> in a React component, when babel transpiled, will return on statement like React.createElement(...)
For example, this
const Search = ({ value, onChange, children }) =>
<form>
{children} <input
type="text"
value={value}
onChange={onChange}
/>
</form>
will be transpiled to
const Search = ({ value, onChange, children }) => React.createElement(...)
You return a single expression in the Search declaration. A compiler reads the declaration ending at the end of that expression (being the closing jsx tag). Personally i prefer to wrap my jsx () => (<div></div>) simply for readability but there's nothing wrong with how your code is.

Arrow function should not return assignment?

My code is working correctly in the app however, my eslint isn't liking it and is saying I should not return assignment. What is wrong with this?
<div ref={(el) => this.myCustomEl = el} />
The Fix:
<div ref={(el) => { this.myCustomEl = el }} />
The Explanation:
Your current code is equivalent to:
<div ref={(el) => { return this.myCustomEl = el }} />
You are returning the result of this.myCustomEl = el. In your code, this is not really a problem -- however, one of the most frustrating bugs in programming occurs when you accidentally use an assignment (=) instead of a comparator (== or ===), for instance:
// This function will always return **true**, surprisingly
function isEqual(a, b) {
// The warning would be thrown here, because you probably meant to type "a===b". The below function will always return true;
return a=b;
}
let k=false;
let j=true;
if(isEqual(k,j)){
// You'll be very, very, very confused as to why this code is reached because you literally just set k to be false and j to be true, so they should be different, right? Right?
thisWillExecuteUnexpectedly();
}
In the above case, the compiler warning makes sense because k=true evaluates to true (as opposed to k===true, which is probably what you meant to type) and causes unintended behavior. Thus, eshint notices when you return an assignment, assumes that you meant to return a comparison, and lets you know that you should be careful.
In your case, you can solve this by simply not returning the result, which is done by adding enclosing brackets {} and no return statement:
<div ref={(el) => { this.myCustomEl = el }} />
You can also adjust the eshint warning like so:
https://eslint.org/docs/rules/no-return-assign
You're implicitly returning an assignment. this.myCustomEl = el is an assignment. You could fix this linting error by changing your arrow function to (el) => { this.myCustomEl =el } which is no longer implicitly returning because you wrapped it in {} instead of ().
Side note: Declaring an arrow function inline inside a render method will break a PureComponent because every time your component renders it has to declare a new anonymous function, so the shallow props comparison that a PureComponent does is broken by this and will always re-render.
Try making that a method of your component.
class MyClass extends React.PureComponent {
getRef = (el) => { this.ref = el; }
render() {
return <div ref={this.getRef} />;
}
}
If the above syntax doesn't work for you, you can use the following:
class MyClass extends React.PureComponent {
constructor(props) {
super(props);
this.ref = null;
this.getRef = this.getRef.bind(this);
}
getRef(el) {
this.ref = el;
}
render() {
return <div ref={this.getRef} />;
}
}
Just wanted to note something I came across. I have Prettier installed and it kept taking away my parens, resulting in eslint error:
To confirm this I added a prettier-ignore:
<div>
{/*prettier-ignore*/}
<Map
ref={(m) => {
this.leafletMap = m;
}}
center={mapCenter}
zoom={zoomLevel}
>
<TileLayer
attribution={stamenTonerAttr}
url={stamenTonerTiles}
/>
</Map>
</div>
Eslint will give us error message if we not applied flowe bracket
Error:
const isNumeric = n => return !isNaN(parseFloat(n)) && isFinite(n)
Solution:
const isNumeric = n => {
return !isNaN(parseFloat(n)) && isFinite(n)
}

Reactjs setState arrow function syntax

As per the React Docs we can have two ways for setState one with object syntax and other with function which they have shown as below
this.setState((prevState, props) => ({
counter: prevState.counter + props.increment
}));
My understanding of arrow function syntax is like () => {} where flower brackets are followed after arrow =>, but as per the sample it is round braces instead of flower brackets
What is the difference between these syntax ()=>{} and ()=>({}).
Sample Code tried as per the docs which is working when this.setStage(prevStage=>({})) syntax is used in handleClick function, and if you change it to this.setState(prevStage=>{}) it wont toggle the button value.
Below is the working code:
class Toggle extends React.Component {
constructor(props) {
super(props);
this.state = {
isToggleOn : true
}
this.handleClick = this.handleClick.bind(this);
}
handleClick() {
this.setState(prevState => ({
isToggleOn: !prevState.isToggleOn
}));
}
render() {
return (
<div>
<button onClick={this.handleClick}>
{this.state.isToggleOn ? 'ON' : "OFF"}
</button>
</div>
);
}
}
There are 2 main issues to consider here:
How arrow functions works?
What setState expects when passing function as a parameter?
Answers:
Arrow functions can return a value implicitly or explicitly.
When
there is no function body (no curly brace {}) then you are
returning implicitly:
const x = () => 'we are returning a string here';
When we use a function body, we need to use the return key word:
const x = () => {
return 'another string returned'
};
There is another option to return something without the return key
word, you can wrap the curly brace with parentheses () and this
will signal the engine that the curly brace are not a function body
but an object, this is considered as creating an expression:
const x = () => ({myKey: 'some string'});
This is similar as we usually do with function expressions.
Especially with IIFE (Immediately Invoked Function
Expression) :
(function() {
//some logic...
})();
If we will not return anything, then the function will just return undefined.
As for setState, when you pass a function as a parameter, it
expect that this function will return an object.
When your function didn't return anything (as stated above) it actually
returned undefined.
JavaScript won't yield an error as this is not
an error. its just a function that returns nothing (undefined).
Here is a running example of your code without the wrapping parentheses:
class Toggle extends React.Component {
constructor(props) {
super(props);
this.state = {
isToggleOn: true
}
this.handleClick = this.handleClick.bind(this);
}
handleClick() {
this.setState(prevState => {
return { // we must return an object for setState
isToggleOn: !prevState.isToggleOn
}
});
}
render() {
return (
<div>
<button onClick={this.handleClick}>
{this.state.isToggleOn ? 'ON' : "OFF"}
</button>
</div>
);
}
}
ReactDOM.render(<Toggle />, document.getElementById('root'));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>
<div id="root"></div>
Edit
As a followup to your comments
I would expect Javascript to throw error when we return just key : value
without enclosing parenthesis, i.e., () => {key:value} - which means
it is trying to return 'key:value' and not Object, and this should be
an JS error, but it did not throw any error. Please correct me if my
understanding is wrong
It is not returning a key value, it is a "void" function that returns undefined.
See this running snippet:
const x = () => {myKey: 'myValue'};
const y = x();
console.log(y);
Edit#2
Followup to your other comments (which is basically kind of a whole different question in my opinion).
let y = function() {'abc':1} - syntax error, let y = function(){abc:1}
and let y = function(){ return {'abc':1} } - no error, where first one
(syntax error) we are trying to assign 1 to string abc, which is same
as 3rd sample (no error), and 2nd example assigning 1 to abc - works
when there is no quotes. Please explain the difference of these 3
samples and why 1st one fails and not 2nd example
OK, this is getting interesting.
where first one (syntax error) we are trying to assign 1 to string abc...
No we are not.
We are trying to create a label:, but labels can't be strings!
Same as variables can't be strings - var 'x' = 1.
This is a valid syntax in JavaScript:
const y = function(){b:2};
What we are doing here is creating a label: named a and this label has an expression of 1 (we are not doing anything with this label.).
const x = () => {a:1};
const y = function(){a:1};
This syntax is invalid:
const y = function() { 'a': 1 };
This is not valid because labels can't start with a string:
const x = () => { 'a': 1 };
const y = function() { 'a': 1 };
And again, this is not a key:value pair, the curly brace are the function's BODY.
Later I referred MDN and found details under Advanced Syntax section, that if you want to return objects implicitly then we need to enclose it within () , that answered my question.
// Parenthesize the body of function to return an object literal expression:
params => ({foo: bar})
the simple answer is
()=>({})
also it's equal to
()=> {
return {}
}
return an empty object,here parentheses around {} mean return. also you know we must pass object to setState so we insert any thing we want to state between {}
()=>({any thing you want to set to state})
If you only write () => {} this explicitly means that the function does more than return something.
For example:
const logAndReturn = (val) => {
console.log(val)
return val
}
But let's say you have a function that takes params and returns an object based on those params.
const createUser = (x) => {
prop: x
}
This will prompt an error cause this translates to:
function createUser(x) {
prop:x
}
With parenthesis, you are still using the default return from the arrow function.
const createUser = (name, email) => ({})
function createUser(name, email) { return {} )

Why does NodeJS throw a TypeError not a function depending on where a function is defined?

I am transpiling an arrow function that looks like this:
const convertToSeconds = milliseconds => Math.round( milliseconds / 1000 );
function fixAllTimestamps( record ) {
if ( record.lastAccessTime ) { record.lastAccessTime = convertToSeconds( record.lastAccessTime ); }
if ( record.licenseExpires ) { record.licenseExpires = convertToSeconds( record.licenseExpires ); }
if ( record.lastModifiedAt ) { record.lastModifiedAt = convertToSeconds( record.lastModifiedAt ); }
if ( record.createdAt ) { record.createdAt = convertToSeconds( record.createdAt ); }
}
Babel seems to do the right thing, because the arrow function gets converted to:
var convertToSeconds = function convertToSeconds(milliseconds) {
return Math.round(milliseconds / 1000);
};
However, when I run this code using node, I get this:
record.lastAccessTime = convertToSeconds(record.lastAccessTime);
^
TypeError: convertToSeconds is not a function
at fixAllTimestamps (test.js:109:29)
This is an unexpected result.
To resolve this, I can either define the arrow function right up at the top of the source code file, before any other functions are defined in the regular Javascript way, or I can put the arrow function definition within the body of fixAllTimestamps so that it becomes a nested function.
Does anybody know why node would fail like this, or is there actually something wrong with my code?
Because you're assigning a function expression to a variable, it needs to be defined before you use it. If you were using a normal function declaration it would get hoisted, and therefore you can use it before it's declaration.
It's because you're using function expression and not function declaration. If you use function declaration, the order of which a function is in your file doesn't matter, if you use function expression, then your function needs to be defined before you use it.
Instead of
var convertToSeconds = function convertToSeconds(milliseconds) {
return Math.round(milliseconds / 1000);
};
Do
function convertToSeconds(milliseconds) {
return Math.round(milliseconds / 1000);
};
Check out my code sample: https://runkit.com/donuts/594352eb72a32300116d5d5e
I'd also like to point out that your function (fixAllTimestamps) is not returning anything. I'm assuming you're hoping it mutates the record.

Categories

Resources