What is this React syntax: inputRef?.current?.current - reactjs

I saw this code snippet in React.
const selected = document.activeElement === inputRef?.current?.current;
Does inputRef?.current?.current equal if (inputRef !== undefined && inputRef.current !== undefined) return inputRef.current

Yes, this is the new features for nodeJS v14.0 called Optional Chaining, it check if the value is !undefined
Thus, inputRef?.current?.current equals to
if (inputRef && inputRef.current) return inputRef.current.current
Please read this interesting post on medium about the most important new features for NodeJS

Related

Why does my local storage item appear to be defined when it isn't?

I'm trying to insert an empty array into localStorage if item doesn't exist:
static getLocalActivities(){
var localActivities = localStorage.getItem("Local-Activities");
if (localActivities === undefined){
LocalStorageFunctions.createLocalActivities()
return JSON.parse(localStorage.getItem("Local-Activities"))
}
else{
if (localActivities.length === 0){return localActivities}
else{
// return JSON.parse(localActivities) // fails because not empty arr
return localActivities;
}
}
}
static createLocalActivities(){
return localStorage.setItem('Local-Activities', []); // < this doesnt work
// return localStorage.setItem('Local-Activities', JSON.stringify([])); // < this doesnt work
}
both methods for creating the item always in application chrome tools show:
Problem
This var localActivities = localStorage.getItem("Local-Activities"); returns 'undefined' and not undefined - take notice that the first one is a string.
This if is always false if (localActivities === undefined){ because localActivities is 'undefined' not undefined
Hence createLocalActivities never runs
Solution
Clear the localStorage value from the dev tools
Use JSON.stringify to save values as suggested in the comments

React Typescript: Object is possibly 'undefined'

I'm using react with typescript and was getting Object is possibly 'undefined' error when return language.toLowerCase().includes(selectedCategory) so I added a checking as in below. Error is gone but I'm not sure whether It can impact the performance. Please advice.
import { filter } from 'lodash';
...
return filter(channels, ({
language
}: Channels) => {
if (
language &&
language.toLowerCase() !== selectedCategory &&
selectedCategory !== 'all'
) {
return false;
}
return (
language && language.toLowerCase().includes(selectedCategory)
);
});
You can use Optional Chaining instead.
If the language is not null or undefined (nullish) it will access the property or method you want otherwise it will return undefined
If you're damn sure about language that it can't be null or undefined then use ! operator (non-null assertion operator) and rewrite your code like this:
import { filter } from 'lodash';
...
return filter(channels, ({
language
}: Channels) => {
return language!.toLowerCase().includes(selectedCategory);
});
Or You can use Optional Chaining instead.
No, that will not impact performance in any way, that's an incredibly inexpensive and common type of check to performance.
You can simplify it though with optional chaining
If you write language?.toLowercase(), it will evaluate to undefined if language is undefined, and a lowercase language if it is defined. So:
if (
language?.toLowerCase() !== selectedCategory &&
selectedCategory !== 'all'
) {
return false;
} else {
return language?.toLowerCase().includes(selectedCategory)
}
If you are sure that the object value is never null or undefined, You can use ! mark:
language!.toLowerCase().includes(selectedCategory)
If you are sure that language will never be undefined, you can use the ! non-null assertion operator to remove that warning.
language!.toLowerCase()
This is the best option in terms of runtime performance since when the code is transpiled into JavaScript the assertion operator is just removed.

use filter only if an attribute exists with map function

Hello I am using filter with map in react.
props.types.filter(data => (data.is_active === 1)).map((data, index) => {
// some code.
});
I am getting props.types in this component. But sometimes props.types does not contain is_active property. So in that case, map function doesn't return anything. I want to run filter only when data.is_active property exists.
How do I do this ?
UPDATE 1:
As I said above I want to run filter only if is_active is exists but I will always run map.
Add a condition to your filter that checks if is_active is not set.
This way your map will always be executed, except when is_active is not 1.
props.types
.filter((data) => data.is_active === undefined || data.is_active === 1)
.map((data, index) => {
// some code.
});
You can add conditional operator "?" after your filter method.
props.types.filter(data => (data.is_active === 1))?.map((data, index) => {
// some code.
});

IF condition with OR inside doesn't work properly React JS

I'm creating plugin for wordpress on react js and got an issue.
When user is entering in admin page and choose for example posts,
I'm checking if it is not a post, so user can't use customizable block:
if ( type !== "post" ) {
return <p>{__("Sorry, Post Navigation block is available only for Posts")}</p>;
}
and it's working, but in wordpress can be more types of posts, so I'm trying to use || inside this condition to check on another type:
if ( type !== "post" || type !== "portfolio" ) {
return <p>{__("Sorry, Post Navigation block is available only for Posts and Portfolio")}</p>;
}
And now is my problem, it's not working.
Variable type I'm getting from here:
const type = wp.data.select('core/editor').getCurrentPostType();
it returns a string.
What am I doing wrong?
Can you help me, please?
if ( type !== "post" || type !== "portfolio" ) {
This will always be true. If type is "post", then it will not be equal to "portfolio". If it's "portfolio", then it will not be equal to "post". And if it's anything else, it will not be equal to either.
Change it to use &&
if ( type !== "post" && type !== "portfolio" ) {

Block a day of the week during a particular month using DateRangePicker

Using the DateRangePicker from react-dates, I wish to disable Mondays, but only during the months of July and August. React is new to me and I don't know how to start solving this problem.
The documentation has a blockedDays prop, but it is not clear to me how I should use it for my particular case.
How can I access the currently displayed month and how can I subsequently block Mondays?
For those who wish to see my code, I have made a gist.
You can achieve this by using the isDayBlocked prop.
This prop is a function callback that will send you a moment date, and require you to send a boolean back, true meaning that the day is blocked and false meaning the opposite.
According to the moment documentation, here is how you will know if your day should be blocked or not :
isDayBlocked = momentDate => {
if (momentDate.format('ddd') === 'Mon' && ['Jul', 'Aug'].includes(momentDate.format('MMM')) return true
return false
}
The following condition would work as well (refer to the doc link above) :
momentDate.format('d') === 0 && [6, 7].includes(momentDate.format('M')
Short syntax :
isDayBlocked = momentDate => momentDate.format('d') === 0 && [6, 7].includes(momentDate.format('M')
And here is the picker :
<DateRangePicker
isDayBlocked={this.isDayBlocked}
// ... your other props
/>
I think I found it. In the code you gave me, you declare the isDayBlocked prop twice :
isDayBlocked={day1 => this.state.disabledDates.some(day2 => isSameDay(day1, day2))} //First time
startDateId="datePickerStart"
endDateId="datePickerEnd"
onDatesChange={this.onDatesChange}
onFocusChange={this.onFocusChange}
focusedInput={focusedInput}
startDate={startDate}
endDate={endDate}
minimumNights={minimumNights}
isOutsideRange={condition}
isDayBlocked = {momentDate => momentDate.format('d') === 0 } // Second one
You can merge them in a single function as shown in my first bit of code and put both conditions inside :
isDayBlocked = momentDate => {
if (momentDate.format('ddd') === 'Mon' && ['Jul', 'Aug'].includes(momentDate.format('MMM')) return true
if(this.state.disabledDates.some(day2 => isSameDay(day1, day2))) return true
return false
}
Following your comment, you have 2 solutions.
Converting the values you want to test to strings :
momentDate => momentDate.format('d') === '0' && ['6','7'].includes(momentDate.format('M')
Or using the non-strict operator :
momentDate => momentDate.format('d') == 0 && ['6', '7'].includes(momentDate.format('M')

Resources