Header at the top in Excel js

I have a function that export excel so it works ver well what i am trying to do is
to have a header in the top excel file and it shows the date of export and under all data

what i tried this :

function RusaltsToCsv(results) {
let header = 'date'
let cols = [
'Name',
'Age'
]
let test = header;
header += new Date().toLocaleDateString()

let res = cols;
res += results.map(r => 
r.name +
r.age
)
return test + res
}

how it is possible to have header at top like this

    02.02.2022
name | Age
test | 20

Google Apps Script: Batch Create Calendar Events with Variable Inputs for CalendarID

I’m trying to make a task-scheduler that can read an a Google Sheet full of tasks (task name, start time, end time, person-assigned-to) and automatically create a calendar event on the specified person’s calendar.

This tutorial:https://cloud.google.com/blog/products/g-suite/g-suite-pro-tip-how-to-automatically-add-a-schedule-from-google-sheets-into-calendar

…has basically all I need, except that it only takes a single CalendarID, whereas I think I need the CalendarID to be part of the loop.

The CalendarID’s in this case are all email addresses.

Here’s what I tried:

function scheduleTasks() {
var spreadsheet = SpreadsheetApp.getActiveSheet();
var signups = spreadsheet.getRange("E9:H13").getValues();
for (x=0; x<signups.length;x++)
{
    var shift = signups[x];
    var calendarID = shift[3];
    var eventCal = CalendarApp.getCalendarById(calendarId);
    var task= shift[0];
    var startTime = shift[1];
    var endTime = shift[2];
    eventCal.createEvent(volunteer, startTime, endTime);
}
}

function onOpen() {
  var ui = SpreadsheetApp.getUi();
  ui.createMenu('Sync to Calendar')
  .addItem('Schedule tasks now', 'scheduleTasks')
  .addToUi();
}

And this is the error I’m getting:

8:38:40 AM Error TypeError: Cannot read property ‘createEvent’ of
null scheduleTasks @ Code.gs:12

Never used JS/Google Apps Script before now so any advice is appreciated,
Thanks

my input data

Manifest v3 Chrome Extension Screen Recording with Background Script

I am trying to create an extension to record screen. In manifest version 2 I was using a persistent background script and calling the start function with chrome.extension.getBackgroundPage() and everything was working perfectly. Now I am trying to migrate to v3 and having problems. Basically what I want to do is start screen record with chrome.desktopCapture in my background script for the active tab.

When I try to run chrome.desktopCapture in background.js chrome shut itself immediately. Since I cannot use getBackgroundPage anymore, I am passing message between the popup and background.

The Code:

// popup.html
chrome.runtime.sendMessage({
    message: "start", 
    tabId: <active-tab-id-here>
    }, (response) => {
           console.log(response.answer);
});


// background.js

chrome.runtime.onMessage.addListener( (request, _, sendResponse) => {
    switch(request.message) {
        case 'start':
               chrome.desktopCapture.chooseDesktopMedia(['tab', 'screen'], onAccessApproved);
    }
    
    sendResponse({answer: "Message Received Successfully!"});
}
);

passing data from textInput value in tab navigator

I have a registration screen , and there is two screens using tab navigation and they are contained with form and the submit button is in main react native page , for giving validation and api call by using the button of main registration page ui but the data collecting from these two tab screens what is the best procedure, please help…

 </View>
            <View style={styles.inputContainer}>
              <MyTab/>
            </View>
            <View style={styles.inpitContainer}>
                <TouchableOpacity
                    onPress={() => registerProcess()}
                    style={styles.btn1}
                >
                    <Text style={styles.btnText}>Save</Text>
                </TouchableOpacity>
</View>
** this is main registration screen with button**
```import React, { useState, useEffect, useRef } from "react";

import { NavigationContainer } from '@react-navigation/native';
import { createMaterialTopTabNavigator } from '@react-navigation/material-top-tabs';

const Tab = createMaterialTopTabNavigator();



const BasicDetails = () => {
   

    const validation = () => {
        console.log("nam", nameVal);
        if (nameVal.length == 0) {
            Alert.alert(
                "Error",
                "Please Enter First Name", [
                {
                    text: "OK", onPress: () => console.log("OK Pressed")
                }
            ], { cancelable: false }
            );
            return false;
        } else if (lastName.length == 0) {
            Alert.alert(
                "Error",
                "Please Enter Your last Name", [
                {
                    text: "OK", onPress: () => console.log("OK Pressed")
                }
            ], { cancelable: false }
            );
            return false;
        }
        return true;
    }

    return (
        <View style={styles.detailContainer}>
            <ScrollView
                showsVerticalScrollIndicator={false}
            >
                <Text>First Name:</Text>
                <TextInput
                    placeholder="Enter First Name"
                    style={styles.textInputContainer}
                    onChangeText={(name) => updateName(name)}
                />
               
            </ScrollView>
           

        </View>
    );
}
const OtherDetails = () => {
    return (
        <View style={styles.detailContainer}>
            <ScrollView
                showsVerticalScrollIndicator={false}
            >
                <Text>Educationlal Qualification:</Text>
                <TextInput
                    placeholder="Enter Educational Qualification"
                    style={styles.textInputContainer}

                />
                <Text>Occupation:</Text>
                
                <Text>About you:</Text>

                <TextInput
                    style={styles.textInputContainer3}
                    multiline={true}
                    numberOfLines={2}
                />

            </ScrollView>

        </View>
    );
}


const MyTab = () => {

    return (
        <NavigationContainer
            independent={true}
        >
            <Tab.Navigator
                initialRouteName="BasicDetails"

                screenOptions={{
                    tabBarActiveTintColor: '#000',

                    tabBarLabelStyle: { fontSize: wp("3.8%"), fontWeight: 'bold', textTransform: 'none' },
                    tabBarIndicatorStyle: {
                        width: wp("22%"), backgroundColor: '#fcb033',
                    },
                    tabBarStyle: {
                        backgroundColor: '#f0f0f0', width: wp("65%"), height: hp("5%"), elevation: 0,
                        shadowColor: "#000000",
                    },
                }}
            >
                <Tab.Screen
                    name="BasicDetails"
                    component={BasicDetails}
                    options={{ tabBarLabel: 'Basic Details' }}
                />
                <Tab.Screen
                    name="OtherDetails"
                    component={OtherDetails}
                    options={{ tabBarLabel: "Other Details" }}
                />

            </Tab.Navigator>
        </NavigationContainer>
    );
}

export default MyTab;
});
**this is the screen MyTab how to give validation and get data for api call**

convert same keys into array in object

i have this type of object of array

const obj =[{
        "id": 1,
        "language": "English",
        "language": "hindi",
        "language": "gujrati"
    }]

and i need to convert this object into this ,
all languages into array,

i want this output(javascript)

const obj =[{
        "id": 1,
        "language": ["English","hindi","gujrati"]
    }]

How to average values in JSON after grouping within a group in javascript

I have a json file with the following data which I would like to group by Year , Theme and then average values on each theme. Can someone help me with this? I have grouped by date and then theme but struggling after that.

[
{“Bid”:”BidTest1″,”QNo”:”1″,”Score”:”0.7″,”Theme”:”Social Value”,”QDate”:”01/01/2021″},
{“Bid”:”BidTest1″,”QNo”:”2″,”Score”:”0.5″,”Theme”:”Tech Mgt”,”QDate”:”01/01/2021″},
{“Bid”:”BidTest1″,”QNo”:”3″,”Score”:”0.8″,”Theme”:”Agile”,”QDate”:”01/01/2021″},
{“Bid”:”BidTest1″,”QNo”:”4″,”Score”:”0.7″,”Theme”:”Social Value”,”QDate”:”01/01/2021″},
{“Bid”:”BidTest456″,”QNo”:”1″,”Score”:”0.5″,”Theme”:”Tech Mgt”,”QDate”:”03/04/2021″},
{“Bid”:”BidTest456″,”QNo”:”2″,”Score”:”0.7″,”Theme”:”Social Value”,”QDate”:”03/04/2021″},
{“Bid”:”BidTest456″,”QNo”:”3″,”Score”:”0.5″,”Theme”:”Agile”,”QDate”:”03/04/2021″},
{“Bid”:”BidHO”,”QNo”:”1″,”Score”:”0.8″,”Theme”:”Agile”,”QDate”:”06/10/2021″},
{“Bid”:”BidHO”,”QNo”:”2″,”Score”:”0.7″,”Theme”:”Social Value”,”QDate”:”06/10/2021″},
]

The code I have used for grouping it is

        let result1 = dataQ1.reduce((state1, current1 ) => {
        let {QDate, Theme} = current1;
        
        let date = state1[QDate] || (state1[QDate] = {});
        let themeArr = date[Theme] || (date[Theme] = []);
       // let monthArr = yearObj[month] || (yearObj[month] = []);
        
        themeArr.push(current1);
        return state1;
     }, {});

This gives me an object with objects containing arrays for each Theme. I need to create a chart grouped by Month, Theme and mark the respective average values per theme.Final Data Sample.

Could someone please guide me on how to go about this ? Thanks

reducing array of objects to sum up for multiple properties

I am having array of objects where i want to reduce the array and get the count of two properties. When my array length is more than one it works but when its one or less it doesn’t

const data = [{id: 1, count:3 , alt_count: 2}, {id: 2, count:4 , alt_count: 5}];
const countObj = data.reduce((acc, curr) => {
      return {
        count_total: acc.count + curr.count,
        alt_count_total: acc.alt_count + curr.alt_count,
      };
    });
 console.log(countObj) // giving me both count_total and alt_count_total

But here its not giving me, instead it gives me the same object

const data = [{id: 1, count:3 , alt_count: 2}];
const countObj = data.reduce((acc, curr) => {
          return {
            count_total: acc.count + curr.count,
            alt_count_total: acc.alt_count + curr.alt_count,
          };
        });
console.log(countObj) // giving me entire first object

Any help is appreciated

Not returning out of an axios get request ( callback function ) correctly

My axios request


function fetchUsersFromLondon() {
  return axios
    .get("https://bpdts-test-app.herokuapp.com/city/London/users")
    .then((response) => {
      return response;
    })

}

module.exports = { fetchUsersFromLondon };

My Jest testing suite

const {fetchUsersFromLondon} = require(".././Models/fetchUsersFromLondon");

describe("Should return an array of objects of people from london", () => {
  test("should ", () => {
    expect(fetchUsersFromLondon()).toEqual([2]);
  });
});

My fetchUsersFromLondon function returns an empty object instead of the data from response. This error is not to do with incorrectly using axios or jest. I have narrowed it down to not returning out of the callback correctly. Any help is appreciated.

Javascript Display block when a button is clicked doesn’t work on mobile

I have this function that checks whether something inside a certain div is clicked. A part of the function checks if the targeted button has a certain class. This works perfectly, but when I go to mobile it doesn’t work like I want it to.

btn.addEventListener("click", function (event) {
        if (!tgt.className.indexOf('nextbtn')) {
            navi.NextBtn();
            let dots = document.getElementsByClassName('owl-dots')[0];
            dots.style.display = 'block';
        }
})

I did a ! in the if statement because somehow it is reversed (I don’t know why). If I remove it it won’t do anything. On my computer it works perfectly, but when I go to mobile it doesn’t change the style to block, but it does run the NextBtn function. Does anybody know how to fix it?

Search for string or number in a string or number

I’m trying to implement a search of an object with multiple key/value pairs that can be either string or number.

This is what I’m currently using (simplified, of course):

const input = 'Hello WORld 21';   // this could also be a number
const search = 'RL';   // this could also be a number
let parsedInput = JSON.stringify(input).toLowerCase().replace(/(^"|"$)/g, '');
let parsedSearch = JSON.stringify(search).toLowerCase().replace(/(^"|"$)/g, '');

if(parsedInput.includes(parsedSearch)) {
  // do stuff
}

So this works, but seems to be expensive, especially when I go through tens of thousands of objects (or even more). So I wonder if there is a more elegant way to implement a search like this.

Thank you in advance!

How to get certain buttons on a html file to disappear and reappear

I’m making a text adventure game that delves into certain rooms on a map. I want, upon entering a certain room, for the corresponding button entering that room to disappear, however, it does not seem to work.

Here is my Code:

                   case 'storage_room':
                       room.innerHTML = "<h2>The Storage Room</h2>";
                       nar.innerHTML = "You enter the Storage Room. You're shocked to discover what's in there...Cages upon cages, stacked to the roof."
                       nar.innerHTML += "And the cages contain...fresh corpses. The smell violates your senses and you feel extremely nauseous."
                       nar.innerHTML += "<span style = 'color:red'>But there is a safe nearby...You could attempt to open it.</span>"
                       document.getElementById('melt_ice').removeAttribute('hidden');
                       document.getElementById('opening_safe').removeAttribute('hidden')
                       document.getElementById('honors_room').removeAttribute('hidden');
                       document.getElementById('lounge_room').removeAttribute('hidden');
                       document.getElementById('open_safe').removeAttribute('hidden');
                       document.getElementById('storage_room').setAttribute('hidden','hidden');
                       document.getElementById('read_plaque').setAttribute('hidden','hidden')
break;

Please help!

Why functions are not working properly in my calculator?

Can you help me identify where’s the problem with this code? I’m a beginner at coding and very likely I’m missing something obvious, but here’s my problem.

When clicking on numbers it seems to work fine, also adding gets to clear the display and (I think) it stores the value in its variable (operandA) but not getting the rest to work, nor the rest of the operands nor the “equals” button.

I have this JS code:

function init(){
    //variables in the calculator
    var result = document.getElementById("result");
    var parenthesisOpen = document.getElementById("parenthesisOpen");
    var parenthesisClose = document.getElementById("parenthesisClose");
    var percent = document.getElementById("percent");
    var allClear = document.getElementById("allClear");
    var zero = document.getElementById("zero");
    var one = document.getElementById("one");
    var two = document.getElementById("two");
    var three = document.getElementById("three");
    var four = document.getElementById("four");
    var five = document.getElementById("five");
    var six = document.getElementById("six");
    var seven = document.getElementById("seven");
    var eight = document.getElementById("eight");
    var nine = document.getElementById("nine");
    var divide = document.getElementById("divide");
    var times = document.getElementById("times");
    var subtract = document.getElementById("substract");
    var float = document.getElementById("float");
    var equals = document.getElementById("equals");
    var add = document.getElementById("add");

    //events
    parenthesisOpen.onclick = function(e){
        result.textContent = result.textContent + "("
    }
    parenthesisClose.onclick = function(e){
        result.textContent = result.textContent + ")"
    }
    zero.onclick = function(e){
        result.textContent = result.textContent + "0"
    }
    one.onclick = function(e){
        result.textContent = result.textContent + "1"
    }
    two.onclick = function(e){
        result.textContent = result.textContent + "2"
    }
    three.onclick = function(e){
        result.textContent = result.textContent + "3"
    }
    four.onclick = function(e){
        result.textContent = result.textContent + "4"
    }
    five.onclick = function(e){
        result.textContent = result.textContent + "5"
    }
    six.onclick = function(e){
        result.textContent = result.textContent + "6"
    }
    seven.onclick = function(e){
        result.textContent = result.textContent + "7"
    }
    eight.onclick = function(e){
        result.textContent = result.textContent + "8"
    }
    nine.onclick = function(e){
        result.textContent = result.textContent + "9"
    }
    float.onclick = function(e){
        result.textContent = result.textContent + "."
    }
    allClear.onclick = function(e){
        clear();
    }
    add.onclick = function(e){
        operandA = result.textContent;
        operator = "+";
        clean();
    }
    subtract.onclick = function(e){
        operandA = result.textContent;
        operator = "-";
        clean();
    }
    times.onclick = function(e){
        operandA = result.textContent;
        operator = "x";
        clean();
    }
    divide.onclick = function(e){
        operandA = result.textContent;
        operator = "/";
        clean();
    }
    equals.onclick = function(e){
        operandB = result.textContent;
        solve();
    }

}
    //Auxiliar Variables
var operandA
var operandB
var operator

    //calculator functions
function clean(){
    result.textContent = "";
}

function clear(){
    result.textContent = "";
    operandA = 0;
    operandB = 0;
    operator = "";
}

function solve(){
    var sol = 0;
    switch(operator){
        case "+":
            sol = parseFloat(operandA) + parseFloat(operandB);
            break;
        
        case "-":
            sol = parseFloat(operandA) - parseFloat(operandB);
            break;
        
        case "x":
            sol = parseFloat(operandA) * parseFloat(operandB);
            break;
        
        case "/":
            sol = parseFloat(operandA) / parseFloat(operandB);
            break;
    }
    clear();
    result.textContent = sol;
}

And this HTML code:

<!DOCTYPE html>
<html>
<head>
    <title>
            Calculator
    </title>
    <link type="text/css" href="style.css" rel="stylesheet">
</head>
<body onload="init();">
    <!--Calculator's structure-->    
    <table class="calculator">
        <!--Calculator's result display-->
    <tr>
        <td colspan="4"><span id="result"></span></td>
    </tr>
        <!--Calculator's buttons-->
    <tr>
        <td><button id="parenthesisOpen">(</button></td>
        <td><button id="parenthesisClose">)</button></td>
        <td><button id="percent">%</button></td>
        <td><button id="allClear">AC</button></td>
    </tr>
    <tr>
        <td><button id="seven">7</button></td>
        <td><button id="eight">8</button></td>
        <td><button id="nine">9</button></td>
        <td><button id="divide">/</button></td>
    </tr>
    <tr>
        <td><button id="four">4</button></td>
        <td><button id="five">5</button></td>
        <td><button id="six">6</button></td>
        <td><button id="times">x</button></td>
    </tr>
    <tr>
        <td><button id="one">1</button></td>
        <td><button id="two">2</button></td>
        <td><button id="three">3</button></td>
        <td><button id="subtract">-</button></td>
    </tr>
    <tr>
        <td><button id="zero">0</button></td>
        <td><button id="float">.</button></td>
        <td><button id="equals">=</button></td>
        <td><button id="add">+</button></td>
    </tr>
    </table>
<script type="text/javascript" src="function.js"></script>
</body>
</html>

Of course, it’s not finished. My aim is to keep on adding features to it, so as to learn while tweaking it.

Thanks in advance!

PS: Yes, there is a raw style sheet in CSS:

.calculator{
    display: block;
    margin: 0 auto;
    padding: 20px;
    background-color: rgb(207, 207, 207); 
    width: 340px;
    height: 580px;
    border-radius: 20px;
    box-shadow: 5px 5px 5px rgb(0, 0, 0);      
}

.calculator td button{
    display: block;
    background-color: rgb(161, 161, 161);
    text-align: center;
    width: 70px;
    height: 70px;
    font-size: 25px;
    border-radius: 100%;
    box-shadow: 2px 2px 2px rgb(0, 0, 0);
}
#equals{
    background-color: rgb(226, 189, 109);
}
#result{
    display: block;
    text-align: center;
    font-size: 40px;
    margin-bottom: 40px;
    width: 300px;
    height: 100px;
    line-height: 100px;
    background-color: aliceblue;
    border-radius: 15px;
    overflow-y:auto;
}

How to not activate or to stop animation on small screen

So i have this animation where there is this a h1 and when i scroll down the image zoom out and the h1 follow the image animation, my problem is that when im on mobile or i resize the screen to tablet or mobile i want the animation on scroll to not activate.
i already tried to use the resize function or if screen is > than but it doesn’t work i’m using scrollMagic cdn.

animation

HTML

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <link rel="stylesheet" href="./Css/style.css">

    <script src="https://cdnjs.cloudflare.com/ajax/libs/ScrollMagic/2.0.8/ScrollMagic.min.js" integrity="sha512-8E3KZoPoZCD+1dgfqhPbejQBnQfBXe8FuwL4z/c8sTrgeDMFEnoyTlH3obB4/fV+6Sg0a0XF+L/6xS4Xx1fUEg==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/ScrollMagic/2.0.8/plugins/debug.addIndicators.min.js" integrity="sha512-RvUydNGlqYJapy0t4AH8hDv/It+zKsv4wOQGb+iOnEfa6NnF2fzjXgRy+FDjSpMfC3sjokNUzsfYZaZ8QAwIxg==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/gsap/3.9.1/gsap.min.js"></script>
    <script src="https://code.jquery.com/jquery-3.6.0.js" integrity="sha256-H+K7U5CnXl1h5ywQfKtSj8PCmoN9aaq30gDh27Xc0jk=" crossorigin="anonymous"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/ScrollMagic/2.0.8/plugins/animation.gsap.js" integrity="sha512-judXDFLnOTJsUwd55lhbrX3uSoSQSOZR6vNrsll+4ViUFv+XOIr/xaIK96soMj6s5jVszd7I97a0H+WhgFwTEg==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>
</head>

<body class="contenet">
    <div class="overflow-wrap">
        <header id="header">
            <img src="./Asset/Img/1.png" loading="lazy" alt="" id="hero-ui">
            <div class="container container--hero">
                <div class="hero__header">
                    <h1 class="hero-heading">The Webflow Expert.</h1>
                </div>
            </div>
        </header>
    </div>
    <section class="section section--manifest">
        <div class="section-header section-header--intro">
            <h2 class="fluid-gradient-heading fluid-gradient-heading--hero cc-en">World-class Webflow<br>sites for ambitious<br>companies.</h2>
        </div>
    </section>

    <script src="./JS/app.js"></script>
</body>

</html>

CSS

* {
    margin: 0;
    padding: 0;
    box-sizing: border-box;
    scroll-behavior: smooth;
}

*::-webkit-scrollbar {
    display: none;
}

body {
    background-color: #1d1d1f;
    color: white;
    font-family: Inter, sans-serif;
    -ms-overflow-style: none;
    /* IE and Edge */
    scrollbar-width: none;
    /* Firefox */
}

#header {
    display: flex;
    height: 100vh;
    align-items: center;
    position: sticky;
    backface-visibility: hidden;
    transform: translate3d(0, 0, 0) scale3d(1, 1, 1);
    transform-style: preserve-3d;
}

.overflow-wrap {
    overflow: hidden;
    height: 100%;
}

#hero-ui {
    position: relative;
    left: 50%;
    z-index: 1;
    width: 16.9em;
    max-width: none;
    margin-top: 3.2em;
    margin-left: -8.45em;
    font-size: 10vw;
    opacity: 0;
}

.hero-heading {
    will-change: transform, opacity;
    animation: fadeIn 0.8s ease;
    animation-iteration-count: 1;
    animation-fill-mode: backwards;
    animation-delay: 0.5s;
    font-size: 92px;
}

.container.container--hero {
    position: absolute;
    left: 0;
    top: 0;
    right: 0;
    bottom: auto;
    display: flex;
    height: 100vh;
    max-width: none;
    padding-top: 100px;
    padding-bottom: 100px;
    flex-direction: column;
    justify-content: center;
    align-items: center;
    text-align: center;
    z-index: 2;
}

.section.section--manifest {
    padding-top: 100px;
    padding-bottom: 160px;
}

.section-header.section-header--intro {
    position: relative;
    max-width: 1050px;
    margin-bottom: 0;
}

.section-header {
    width: 90%;
    max-width: 980px;
    margin-right: auto;
    margin-bottom: 142px;
    margin-left: auto;
    text-align: left;
}

.fluid-gradient-heading.fluid-gradient-heading--hero.cc-en {
    font-size: 103px;
}

.fluid-gradient-heading.fluid-gradient-heading--hero {
    margin-right: auto;
    margin-left: auto;
    line-height: 1.05;
    text-align: center;
}

.fluid-gradient-heading {
    background: linear-gradient(91.36deg, #ECA658 0%, #F391A6 13.02%, #E188C3 25.52%, #A58DE3 37.5%, #56ABEC 49.48%, #737EB7 63.02%, #C8638C 72.92%, #DD5D57 84.38%, #DF6C51 97.92%);
    background-size: 200% 200%;
    -webkit-background-clip: text;
    background-clip: text;
    -moz-background-clip: text;
    -webkit-animation: intro-gradient 10s infinite ease both;
    -moz-animation: intro-gradient 10s infinite ease both;
    animation: intro-gradient 10s infinite ease both;
}

.fluid-gradient-heading {
    margin-top: 0;
    padding-top: 8px;
    padding-bottom: 8px;
    font-size: 92px;
    line-height: 1.1;
    letter-spacing: -.045em;
    -webkit-background-clip: text;
    background-clip: text;
    -webkit-text-fill-color: transparent;
}

h2 {
    margin-top: 20px;
    margin-bottom: 10px;
    font-size: 32px;
    line-height: 36px;
    font-weight: 600;
}

JAVASCRIPT

/*==================== zoom out image ====================*/


let controller = new ScrollMagic.Controller();
let zoomHeader = TweenMax.to("#header", 0.9, { opacity: 1, scale: 0.35, ease: Circ.EaseIn });
let headerZoom = new ScrollMagic.Scene({
        triggerElement: "#header",
        triggerHook: 0,
        duration: "3000ms"
    })
    .setPin('#header')
    .setClassToggle('#header')
    .setTween(zoomHeader)

.addTo(controller);

/*==================== smooth link scrooling====================*/
let $root = $('html, body');

$('a[href^="#"]').click(function() {
    $root.animate({
        scrollTop: $($.attr(this, 'href')).offset().top
    }, 500);

    return false;
});


/*==================== Change opacity image ====================*/
$(window).scroll(function() {
    let scrollTop = $(this).scrollTop();

    $('#hero-ui').css({
        opacity: function() {
            let elementHeight = $(this).height();
            return 1 - (elementHeight - scrollTop) / elementHeight;
        }
    });
});

Is it okey to use side effects in the useState hook callback?

Imagine situation:

const [value, setValue] = useState(false);

const setSomething = (val) => {
  setValue((prev) => {
    fn(); dispatch(action); // or any other side effect
    
    return prev + val;
  });
};

Is it programmatically okey and fine with react principles to call side effects inside useState callback? May it affect the render process somehow?