I wonder if this
const getData = () => {
const data = 1; // simplified complicated operations
return data;
};
export default getData();
is any performance difference than this:
const getData = () => {
const data = 1;
return data;
};
const toexport = getData(); // cache to a variable before exporting
export default toexport;
The question boils down to how export actually works. I read many articles and I can manage to make it work, but I haven't understood what it does under the hood (couldn't find an article about my question).
What if an export is imported from difference import, will the getData() be called once or being called for each import?
function getData() {
console.log('getData');
return 1;
}
// will `export default getData();` be like this
const importSomeWhere = getData();
const importSomeWhereElse = getData();
// or this?
const exportCached = getData();
const importSomeWhere2 = exportCached;
const importSomeWhereElse2 = exportCached;
It will be evaluated only once. Here's example from What Happens When a Module Is Imported Twice?
In increment.js, we declare a variable called counter
let counter = 0;
counter++;
export default counter;
In consumer.js we import 2 times, but the counter is evaluated once for the first import
import counter1 from './increment';
import counter2 from './increment';
counter1; // => 1
counter2; // => 1
Related
import React from 'react';
const RowArray=()=>{
return(
<div>
<h1>Row Array</h1>
</div>
)
};
const chunk_array = (list, integer)=>{
let temp_arr = list;
console.log('chunks',list,'integer',integer);
const list_of_chunks = [];
const iteration = Math.ceil(+list.length/+integer);
// list.map(x => {console.log(x,"map")})
for (let i;i< iteration ;i++ ){
console.log(i);
let temp_chunk = temp_arr.splice(6, temp_arr.length);
list_of_chunks.push(temp_chunk);
};
return list_of_chunks;
}
const TableArray=({details})=>{
const data = chunk_array(details);
console.log('data', data);
return(
<div className="d-flex flex-row">
<RowArray/>
</div>
)
};
export default TableArray;
the for loop in function chunk array won't work, supported as no i was logged in the console. I understand in jsx for loop may not work, I believe I define the function in pure javascript enviroment, so why do you think it is?
Console.log(i) doesn't log anything, as in the function skipped for loop line
you haven't initialized the value of i in the for loop
for (let i = 0; i < iteration; i++) {
// your code
}
chunk_array function expects two arguments and you're only passing one argument details
I am coming from vue and used to composable functions. I am trying to figure out the way to do this in svelte
So I make a js file and import store and then was trying to make a function that I could call on multiple components and act individually
swipe.js file
import { writable, derived, get } from 'svelte/store';
function createSwipe() {
const dyFromStart = writable(0)
function moveEvent(eventType, val){
console.log('moveEvent', eventType, val, get(dyFromStart))
dyFromStart.update(n => n + 1);
}
const dxScore = derived(dyFromStart, $dyFromStart => $dyFromStart + 3)
const dyScore = derived(dyFromStart, $dyFromStart => Math.round($dyFromStart + 100));
return {
moveEvent,
dxScore,
dyScore,
};
}
export const swipe = createSwipe();
then in .svelte component import function in script and decompose into subparts
<script>
import { swipe } from "$lib/swipe";
let { moveEvent, dxScore, dyScore } = swipe
</script>
<p>{$dxScore}{$dyScore}</p>
<button on:click="() => moveEvent">button</button>
Well eventually I want to turn into a swipe component hence name but trying to get fundamentals down. So I want to be able to have unique store for each component and for this if I use multiple of this .svelte component the state is shared amongst all.
And not just like three idk modal.svelte components I want to use swipe for a bunch of diff components maybe a photoViewer.svelte right just generic swipe function and use same code for all.
or would I just have to keep the state like const dyFromStart = writable(0) be just let dyFromStart = 0 in each .svelte component and pass it into a pure js function that returns results and update local .svelte variables
Adding this as the non store more pure js things I was trying but couldn't get to be reactive so accepting the answer below on store method that worked and sounds like is the correct approach
export function createSwipe() {
let dyFromStart = 0
function moveEvent(eventType, val){
console.log('moveEvent', eventType, val, dyFromStart, dxScore(), dyScore())
dyFromStart++
}
function dxScore(){ return dyFromStart + 3 }
// const dzScore = derived(dyFromStart, $dyFromStart => $dyFromStart + 3)
const dyScore = () => Math.round(dyFromStart + 100)
return {
moveEvent,
dxScore,
dyScore,
dyFromStart
};
export function createSwipe() {
let dyFromStart = 0
let dxScore = dyFromStart + 3
let dyScore = Math.round(dyFromStart + 100)
function moveEvent(eventType, val){
console.log('moveEvent', eventType, val, dyFromStart, dxScore, dyScore)
dyFromStart++
dxScore = dyFromStart + 3
dyScore = Math.round(dyFromStart + 100)
}
return {
moveEvent,
dxScore,
dyScore,
dyFromStart
};
I suppose that works fine just not reactive with $ and need to call to update a diff local var if doing that
this would seem most sveltey to me or something like it as far as composable function type style not store type
export function createSwipe() {
let dyFromStart = 0
function moveEvent(eventType, val){
console.log('moveEvent', eventType, val)
dyFromStart++
}
$: dxScore = dyFromStart + 3
$: dyScore = Math.round($dyFromStart + 100)
return {
moveEvent,
dxScore,
dyScore,
};
}
I don't understand the question fully, so I try to reiterate first what I think you want:
You want to use your swipe function in multiple places
Each usage of that swipe function should be independent of all others
If that's correct, then the answer is simple: Don't do export const swipe = createSwipe(). Delete that part and instead export the create function to use directly within your components. That way you create a new independent instance each time:
<script>
import { createSwipe } from "$lib/swipe";
let { moveEvent, dxScore, dyScore } = createSwipe()
</script>
<p>{$dxScore}{$dyScore}</p>
<button on:click="() => moveEvent">button</button>
I am trying to generate a unique id number for each React component, this id will be assigned to the component when it is mounted.
I am using the code below, the function callOnce takes a function and ensure that the function is only executed once per component.
import React, { useRef } from "react";
// Helper function that makes fn execute only once
const callOnce = (fn) => {
let called = false;
let result;
return (...params) => {
if (called) return result;
called = true;
result = fn(...params);
return result;
};
};
let lastId = 0;
const getId = () => {
console.log("incrementing");
lastId = lastId + 1;
return lastId;
};
export default function App() {
const { current: getIdOnce } = useRef(callOnce(getId));
const id = getIdOnce();
return <div>{id}</div>;
}
When I execute this code, the id that is displayed is 2, but logically it should be 1.
The getId function is only called once (the message incrementing is printed once), so there is no other way that the variable lastId is incremented again.
Why is the value 2 ?
codesandbox link
I not know what the problem, but the fix can be that:
import React, { useRef } from "react";
// Helper function that makes fn execute only once
const callOnce = (fn) => {
let called = false;
let result;
return (...params) => {
if (called) return result;
called = true;
result = fn(...params);
return result;
};
};
let lastId = 0;
const getId = () => lastId++;
export default function App() {
const { current: getIdOnce } = useRef(callOnce(getId));
const id = getIdOnce();
return <div>{id}</div>;
}
If I found the problem reason, I will update my comment ☺
I found the answer in another thread. Basically when using React with React.StrictMode wrapper, some functions are executed twice.
The reason the id is 2 is because the function getId is executed twice
Link of the answer with more details
I wanna create a logout function that should reset all the counters. Therefore, I need to access the countervariables from another module (and set them to the original value). How can I do that within javascript and react?
Here is my import declaration and the logoutUser function from the AuthState.js file:
import chatState from "../Chat/ChatState";
const logoutUser = () => {
console.log(questioncounter);
chatState.questioncounter = 2;
chatState.questioncounter_event = 1;
chatState.currentNode = 1;
dispatch({
type: LOGOUT_USER,
});
};
And here are the local variables from ChatState.js:
let questioncounter = 2;
let questioncounter_event = 1;
let currentNode = 1;
I want to render state that is updated every request animation frame.
I want to encapsulate state with an update method and corresponding component:
But that fails because it's not correct usage of mithril components.
import * as Vnode from 'mithril/render/vnode';
import * as h from 'mithril/hyperscript';
export default function Play() {
// background is another encapsulation like Play
let background = new Background(this);
let data;
this.init = d => {
data = d;
background.init();
};
this.update = delta => {
background.update(delta);
};
this.component = ({
view() {
return h('div.' + data,
[Vnode(background.component)]
);
});
}
Render code:
import mrender from 'mithril/render';
import * as Vnode from 'mithril/render/vnode';
export default function MRender(mountPoint) {
this.render = (component) => {
mrender(mountPoint, Vnode(component));
};
}
Usage:
let mrender = new MRender(element);
let play = new Play();
function step() {
play.update();
mrender.render(Vnode(play.component));
requestAnimationFrame(step);
};
step();
I want state mutations and render code to be in the same place, because state is concerned with view animations.
If I understand correctly you want to be able to manage the internal state of the component while it's being updated by requestAnimationFrame? The following might get you on the right track:
const m = require('mithril');
//Use a closure to manage internal state of component
const play = initialVnode => {
const {
timestamp
} = initialVnode.attrs;
const start = timestamp;
return {
view: vnode => m('ul',[
m('li',`Start: ${start}`),
m('li',`Current timestamp: ${vnode.attrs.timestamp}`),
])
}
};
let reqID;
const step = timestamp => {
if( timestamp ){ //Start animating when timestamp is defined
m.render(document.body, m(play,{
timestamp,
}));
}
reqID = requestAnimationFrame(step);
if( reqID === 60 ){ //Add condition to stop animating
cancelAnimationFrame(reqID);
}
};
step();
I hope that helps.