how can I get the Index of city cliked and pass it to function Daily.js
exemple when user change location to differnt city I want to change the Url
in the list location 1 => url 1
location2 => url 2
...
function Daily({ locationProps = 1, root }) {
const context = useContext(ThemeContext);
const localization = useCallback(() => {
if (root && cookies.get("location") !== undefined) {
return cookies.get("location");
}
return locationProps;
}, [locationProps, root]);
const handleClick = event => {
window.focus();
notification.close(event.target.tag);
};
const openNav = () => {
document.getElementById("sidenav").style.width = "100%";
};
const closeNav = e => {
e.preventDefault();
document.getElementById("sidenav").style.width = "0";
};
const _data = useRef(new Data(INDEX)); // -----> How to pass INDEX here !
const getTimes = () => _data.current.getTimes();
const times = useState(()=>getTimes());
data.json
location [
liste of location
],
URL [
list of url
]
Related
I have a markets screen where I am using sockets to update the prices of cryptocurrencies in real time. The screen contains an infinite scroller, so when the user scrolls, more cryptocurrencies load and the coins being observed by the socket changes as well. However I am noticing as the coins list is increasing, the app becomes really slow and I cannot navigate to other screens or click anywhere quickly.
I have seen a few apps achieve this infinite-scroll-live-prices logic such as CoinGecko & CoinMarketCap.
Snippet of the relevant code:
const updatePriceOfCoins = (newPrices = {}, coins = []) => {
const updatedCoins = [...coins];
let wasUpdated = false;
for (let i = 0; i < updatedCoins.length; i++) {
let coin = updatedCoins[i];
if (newPrices[coin.id] !== undefined) {
updatedCoins[i] = { ...coin, priceUsd: newPrices[coin.id] };
wasUpdated = true;
}
}
return { wasUpdated, coins: updatedCoins };
};
const MarketsScreen = ({
markets,
getMarkets,
isLoading,
isLoadingMore,
perPage,
getMoreMarkets,
hasMore,
updateMarkets
}) => {
const socket = useLivePrices(markets);
const marketsRef = useRef(markets);
useEffect(() => {
marketsRef.current = markets;
}, [markets]);
const onNewPrices = (newPrices) => {
const { wasUpdated, coins: updatedMarkets } = updatePriceOfCoins(newPrices, marketsRef.current);
if (wasUpdated) {
updateMarkets(updatedMarkets);
}
};
useEffect(() => {
getMarkets();
}, []);
useEffect(() => {
if (socket !== null) {
socket.on("new prices", onNewPrices);
}
return () => {
if (socket !== null) {
socket.off("new prices");
}
};
}, [socket]);
return (
<FlatList
data={data}
renderItem={renderDataItem}
showsVerticalScrollIndicator={false}
onEndReached={getMoreMarkets}
onEndReachedThreshold={0.5}
/>
);
};
useLivePrices hook
const useLivePrices = (coinsToWatch = []) => {
const [socket, setSocket] = useState(null);
const prevCommaSepCoins = useRef("");
useEffect(() => {
//Only initialize socket once then everytime coinsToWatch is different
//update the coins observed
if (coinsToWatch.length > 0) {
if (socket === null) {
const commaSepCoins = coinsToCommaSepIDs(coinsToWatch);
setSocket(connectToLivePricesSocket(commaSepCoins));
prevCommaSepCoins.current = commaSepCoins;
} else {
const newCommaSepCoins = coinsToCommaSepIDs(coinsToWatch);
if (prevCommaSepCoins.current !== newCommaSepCoins) {
socket.emit("update coins", newCommaSepCoins);
prevCommaSepCoins.current = newCommaSepCoins;
}
}
}
}, [coinsToWatch]);
useEffect(() => {
let unsubFocus = () => {};
let unsubBlur = () => {};
if (socket !== null) {
//pause and resume prices based on if screen is in focus
unsubFocus = navigation.addListener("focus", resumePrices);
unsubBlur = navigation.addListener("blur", pausePrices);
}
return () => {
if (socket !== null) {
socket.disconnect();
unsubFocus();
unsubBlur();
}
};
}, [socket]);
return socket;
};
I want to achieve the infinite-scroll-live-prices but not sure how to optimize the performance anymore.
I tried optimizing the performance by reducing the number of renders when price updates. I have also tried to pause and resume the socket based on if the screen is focused so that state updates are not happening while the screen is not focused.
I have these two functions that take data from a google sheet and then send a whatsapp message. I can't modify the first function (getSheetData_) to take only the data from the last row. I only have two columns (name and phone). I have a trigger that launches the script on every change.
source: https://www.labnol.org/whatsapp-api-google-sheets-220520
const getSheetData_ = () => {
const [header, ...rows] = SpreadsheetApp.getActiveSheet().getDataRange().getDisplayValues();
const data = [];
rows.forEach((row) => {
const recipient = { };
header.forEach((title, column) => {
recipient[title] = row[column];
});
data.push(recipient);
});
return data;
};
const main = () => {
const data = getSheetData_();
data.forEach((recipient) => {
const status = sendMessage_({
recipient_number: recipient["Phone Number"].replace(/[^\d]/g, ""),
customer_name: recipient["Customer Name"]
});
});
};
Solution:
const getSheetData_ = () => {
var sheet = SpreadsheetApp.getActiveSheet();
var lastRow = sheet.getRange(sheet.getLastRow(),1,1,2);
const header = ['Customer Name', 'Phone Number'];
const rows = lastRow.getDisplayValues();
const data = [];
rows.forEach((row) => {
const recipient = { };
header.forEach((title, column) => {
recipient[title] = row[column];
});
data.push(recipient);
});
return data;
};
I'm doing a push to the array with the data, but when I set the array to the state I got several objects in the console, with the same content.
When the data clicked on map isn't equal to the first data on the array, the user still can click on other coordinates.
:
const [showPolygonForm, setShowPolygonForm] = useState(false)
const [polyData, setPolyData] = useState([])
const revealPolygonForm = () => {
setShowPolygonForm(!showPolygonForm)
}
const createPolygon = () => {
let arrayValores = []
if(showPolygonForm === true){
map.on('click', e => {
const data = {
lat: e.latlng.lat,
lng: e.latlng.lng
}
arrayValores.push(data)
setPolyData(arrayValores)
console.log(arrayValores)
})}
if(polyData[0] != polyData[(polyData.length - 1)]){
console.log("it's in")
map.on('click', e => {
arrayValores.push(e.latlng)
})}
}
createPolygon()
In the line setVotedPosts([...previousVotedPosts, postId]);
I'm trying to get the previous value of votedPosts, but I'm getting back the newest value.
full code : https://github.com/silvertechguy/reddit-clone/blob/main/src/components/vote-buttons.js
App live : https://reddit-clone-official.vercel.app/
const VoteButtons = ({ post }) => {
const [isVoting, setVoting] = useState(false);
const [votedPosts, setVotedPosts] = useState([]);
useEffect(() => {
const votesFromLocalStorage =
JSON.parse(localStorage.getItem("votes")) || [];
setVotedPosts(votesFromLocalStorage);
}, []);
const handleDisablingOfVoting = (postId) => {
const previousVotedPosts = votedPosts;
setVotedPosts([...previousVotedPosts, postId]);
localStorage.setItem(
"votes",
JSON.stringify([...previousVotedPosts, postId])
);
};
const handleClick = async (type) => {
setVoting(true);
// Do calculation to save the vote.
let upVotesCount = post.upVotesCount;
let downVotesCount = post.downVotesCount;
const date = new Date();
if (type === "upvote") {
upVotesCount = upVotesCount + 1;
} else {
downVotesCount = downVotesCount + 1;
}
await db.collection("posts").doc(post.id).set({
title: post.title,
upVotesCount,
downVotesCount,
createdAt: post.createdAt,
updatedAt: date.toUTCString(),
});
// Disable the voting button once the voting is successful.
handleDisablingOfVoting(post.id);
setVoting(false);
};
const checkIfPostIsAlreadyVoted = () => votedPosts.includes(post.id);
Problem
const previousVotedPosts = votedPosts;
In JavaScript, arrays are reference types, so you can't just create a new copy of an array using =.
Try this solution
Clone array using spread syntax(...).
const handleDisablingOfVoting = (postId) => {
const previousVotedPosts = [...votedPosts];
setVotedPosts([...previousVotedPosts, postId]);
localStorage.setItem(
"votes",
JSON.stringify([...previousVotedPosts, postId])
);
};
Need help passing data "locationpos"= index of my Locations[] from function to class. I'm very new to React and I'm not sure what I'm doing wrong.
ERROR
Failed to compile
./src/components/data.js
Line 20:30: 'locationpos' is not defined no-undef
Search for the keywords to learn more about each error.
This error occurred during the build time and cannot be dismissed.
class Data {
constructor(locationpos) {
this.locationpos=locationpos;
this.updateData();
}
getTimes(date = null) {
date = date === null ? moment().format('DD/MM/YYYY') : date;
var data = this.getData();
return data ? data[date] : [];
}
getSpeadsheetUrl() {
return config.myData[locationpos];
}
function Daily({ locationProps = 1, root }) {
const context = useContext(ThemeContext);
const localization = useCallback(() => {
if (root && cookies.get("location") !== undefined) {
return cookies.get("location");
}
return locationProps;
}, [locationProps, root]);
const [locationState] = useState(localization());
const handleClick = event => {
window.focus();
notification.close(event.target.tag);
};
const openNav = () => {
document.getElementById("sidenav").style.width = "100%";
};
const closeNav = e => {
e.preventDefault();
document.getElementById("sidenav").style.width = "0";
};
// eslint-disable-next-line
const locationpos = locations.indexOf(locations[locationState]);
const _data = useRef(new Data(locationpos));
const getTimes = () => _data.current.getTimes();
Inside your data class, you need to use the instance variable as this.locationPos
getSpeadsheetUrl() {
return config.myData[this.locationpos];
}