I have in my file index.Js :
const toto = ({tokenMode = false}) => {
const bPrice = usePriceB();
const aPrice = usePriceA();
return (
<SectionWrapper
section={{
title: tokenMode ? 'Pools' : 'Farming',
id: tokenMode ? 'pools' : 'farming',
cards: generateCards().slice(0, 3),
}}
>
<Card cards={generateCards().slice(0, 3)} ethereum={window.ethereum}/>
</SectionWrapper>
);
}
export default toto;
How to call variable aPrice and bPrice in other file .js ?
Edit : I just added my return of this function
might need more info about intended use, but based on the info provided I'd guess you can do
const toto = ({tokenMode = false}) => {
const bPrice = usePriceB();
const aPrice = usePriceA();
return {aPrice, bPrice};
}
export default toto;
this will return the variables as an object that you can then get the values from
you could then use...
const toto = require('./toto.js');
const tamto = toto();
console.log(tamto.aPrice);
console.log(tamto.bPrice);
Update
In the context of a react app , you could use useState
import React, { useState, useEffect } from 'react';
export const getters = {
aPrice:null,
bPrice:null
}
const setters = {
aPrice:null,
bPrice:null
}
export const Toto = () => {
[getters.aPrice , setters.aPrice] = useState(null);
[getters.bPrice , setters.bPrice] = useState(null);
// runs once
useEffect(() => {
setters.aPrice(usePriceA());
setters.bPrice(usePriceB());
}, []);
return (
<SectionWrapper>
...
</SectionWrapper>
)
}
Then you can have the getters and Toto available
import {Toto, getters} from `index.js`
//...
console.log(getters.aPrice);
Related
//Journal.js
//...
let num;
const onPress = async() => {
// code gives num a value
num = 2
}
//...
export num;
export defualt Journal;
//Analysis.js
import {num} from './Journal';
//...
const someVar = num;
To my knowledge, it seems the Analysis page builds before the the user can select the OnPress function. When the OnPress function is pressed, Javascript doesnt rexport the variable num that needs to be used in Analysis. How do I utilize the updated value of num (which is updated after the onPress function is pressed in the Journal.js) in Analysis.js?
Sounds like you should be storing num in some central state (eg redux) or context.
For example
// contexts/mood.js
import { createContext, useState } from "react";
const MoodContext = createContext({ num: null, setNum: () => {} });
const MoodContextProvider = ({ children }) => {
const [num, setNum] = useState();
return (
<MoodContext.Provider value={{ num, setNum }}>
{children}
</MoodContext.Provider>
);
};
export { MoodContext, MoodContextProvider };
You can then write a custom hook to use this context and expose your analysis functionality.
// hooks/mood-analysis.js
import { useContext } from "react";
import { MoodContext } from "../contexts/mood";
const useMoodAnalysis = () => {
const { setNum } = useContext(MoodContext);
return async (inputValue) => {
// ...
setNum(2);
};
};
All that's left is to wrap your components in the provider...
<MoodContextProvider>
<Routes>
{/* ... just an example ... */}
</Routes>
</MoodContextProvider>
use the hook in your Journal component...
const analyse = useMoodAnalysis();
const onPress = async () => {
// ...
await analyse(someInputValue);
};
and read the context value in your Analysis component
const { num } = useContext(MoodContext);
Is that possible to use a variable of different function in another component ? I seperated function part and component part that is like :
and my function:
export function createCombos(number_of_cells) {
number_of_cells = parseInt(number_of_cells);
const real_number = Math.sqrt(number_of_cells);
const arr = Array(real_number)
.fill(0)
.map((x) => Array(real_number).fill(0));
}
I want to use "arr" which I declared in "createCombos" function.
The component that I wanted to use in :
I want to use like that :
import { createCombos } from "../functions/Combo";
import { useEffect, useState } from "react";
export default function Board() {
var [arra, setArra] = useState([]);
useEffect(() => {
createCombos(prompt("enter a number:"));
**setArra(createCombos.arr);**
});
return <div>
**arra.map((a)=> {
<p> {a} </p>
})**
</div>;
}
How can I do that? Thanks!
in Combo.js, return the array from createCombos function.
export function createCombos(number_of_cells) {
number_of_cells = parseInt(number_of_cells);
const real_number = Math.sqrt(number_of_cells);
const arr = Array(real_number)
.fill(0)
.map((x) => Array(real_number).fill(0));
return arr
}
change the React component to this.
import { createCombos } from "../functions/Combo";
import { useEffect, useState } from "react";
export default function Board() {
var [arra, setArra] = useState([]);
useEffect(() => {
// save returned array to arr variable
const arr = createCombos(prompt("enter a number:"));
setArra(arr);
});
return <div>
arra.map((a)=> {
<p> {a} </p>
})
</div>;
}
I have implemented the following custom hook:
export default function useCamera() {
const [cameraRatio, setCameraRatio] = useState(Camera.Constants.DesiredRatio);
const [cameraType, setCameraType] = useState(Camera.Constants.Type.back);
const [flashMode, setFlashMode] = useState(
Camera.Constants.FlashMode.off
);
const camRef = useRef(null); <----- Interesting part
const cameraTypeRef = useRef(cameraType);
const isTakingPhoto = useRef(false);
const takePhoto = () => {
if(!camRef.current) return; <----- Interesting part
...
}
const flip = () => {}
const toggleFlash = () => {}
...
return {
camRef,
cameraRatio,
cameraType,
flashMode,
takePhoto,
flip,
toggleFlashMode,
...
}
}
So, in my Camera component, I just do:
function Camera({ ... }) {
const {
camRef, <---- Interesting part
takePhoto,
...
} = useCamera();
return <NativeCamera ref={camRef} onTakePhoto={takePhoto} ... />
}
As you can see, I am passing the camRef to "NativeCamera". This ref is defined in my custom hook "useCamera", and received in my "Camera" component, which just pass the ref to the child.
But this doesn't work. Any workaround?
My goal is to use custom hooks created from Context to pass and modify stored values
The final goal is to use something like useFeedContext() to get or modify the context values
What I am actually getting is either the functions that I call are undefined or some other problem ( I tried multiple approaches)
I tried following this video basics of react context in conjunction with this thread How to change Context value while using React Hook of useContext but I am clearly getting something wrong.
Here is what I tried :
return part of App.js
<FeedProvider mf={/* what do i put here */}>
<Navigation>
<HomeScreen />
<ParsedFeed />
<FavScreen />
</Navigation>
</FeedProvider>
Main provider logic
import React, { useState, useEffect, useContext, useCallback } from "react";
import AsyncStorage from "#react-native-async-storage/async-storage";
const FeedContext = React.createContext();
const defaultFeed = [];
const getData = async (keyName) => {
try {
const jsonValue = await AsyncStorage.getItem(keyName);
return jsonValue != null ? JSON.parse(jsonValue) : null;
} catch (e) {
console.log(e);
}
};
const storeData = async (value, keyName) => {
console.log(value, keyName);
try {
const jsonValue = JSON.stringify(value);
await AsyncStorage.setItem(keyName, jsonValue);
} catch (e) {
console.log(e);
}
};
export const FeedProvider = ({ children, mf }) => {
const [mainFeed, setMainFeed] = useState(mf || defaultFeed);
const [feedLoaded, setFeedLoaded] = useState(false);
let load = async () => {
let temp = await AsyncStorage.getItem("mainUserFeed");
temp != null
? getData("mainUserFeed").then((loadedFeed) => setMainFeed(loadedFeed))
: setMainFeed(defaultFeed);
setFeedLoaded(true);
};
useEffect(() => {
load();
}, []);
useCallback(async () => {
if (!feedLoaded) {
return await load();
}
}, [mainFeed]);
const setFeed = (obj) => {
setMainFeed(obj);
storeData(mainFeed, "mainUserFeed");
};
return (
<FeedContext.Provider value={{ getFeed: mainFeed, setFeed }}>
{children}
</FeedContext.Provider>
);
};
//export const FeedConsumer = FeedContext.Consumer;
export default FeedContext;
The custom hook
import { useContext } from "react";
import FeedContext from "./feedProviderContext";
export default function useFeedContext() {
const context = useContext(FeedContext);
return context;
}
What I would hope for is the ability to call the useFeedContext hook anywhere in the app after import like:
let myhook = useFeedContext()
console.log(myhook.getFeed) /// returns the context of the mainFeed from the provider
myhook.setFeed([{test:1},{test:2}]) /// would update the mainFeed from the provider so that mainFeed is set to the passed array with two objects.
I hope this all makes sense, I have spend way longer that I am comfortable to admit so any help is much appreciated.
If you want to keep using your useFeedContext function, I suggest to move it into the your 'Provider Logic' or I'd call it as 'FeedContext.tsx'
FeedContext.tsx
const FeedContext = createContext({});
export const useFeedContext = () => {
return useContext(FeedContext);
}
export const AuthProvider = ({children}) => {
const [mainFeed, setMainFeed] = useState(mf || defaultFeed);
...
return (
<FeedContext.Provider value={{mainFeed, setMainFeed}}>
{children}
</FeedContext.Provider>
);
};
YourScreen.tsx
const YourScreen = () => {
const {mainFeed, setMainFeed} = useFeedContext();
useEffect(() => {
// You have to wait until mainFeed is defined, because it's asynchronous.
if (!mainFeed || !mainFeed.length) {
return;
}
// Do something here
...
}, [mainFeed]);
...
return (
...
);
};
export default YourScreen;
I am trying to do a withCache HoC component but having some problems...
Thats the HoC:
// HOC for cached images
const withCache = (Component) => {
const Wrapped = (props) => {
console.log(props);
const [uri, setUri] = useState(null);
useEffect(() => {
(async () => {
const { uri } = props;
const name = shorthash.unique(uri);
const path = `${FileSystem.cacheDirectory}${name}`;
const image = await FileSystem.getInfoAsync(path);
if (image.exists) {
console.log("Read image from cache");
setUri(image.uri);
return;
} else {
console.log("Downloading image to cache");
const newImage = await FileSystem.downloadAsync(uri, path);
setUri(newImage.uri);
}
})();
}, []);
return <Component {...props} uri={uri} />;
};
Wrapped.propTypes = Component.propTypes;
return Wrapped;
};
export default withCache;
The thing is that "Component" is a custom Image component with specific propTypes and defaultProps.
How do I use this component? I have tried:
const CachedImage = withCache(<MyCustomImage uri={"https://..."} height={100} ripple />)
...
return (<CachedImage />)
but not working :( What I want is to pass a boolean prop to my custom image component named "cached", and if true return the custom image component wrapped in the HOC
In order to use the HOC, you would create the instance outside of the functional component like
const CachedImage = withCache(MyCustomImage)
and use it like
const MyComp = () => {
...
return (<CachedImage uri={"https://..."} height={100} ripple />)
}
Final implementation of the HoC, in case someone finds it useful in the future.
import React, { useState, useEffect } from "react";
import shorthash from "shorthash";
import * as FileSystem from "expo-file-system";
// HOC for cached images
const withCache = (Component) => {
const Wrapped = (props) => {
console.log(props);
const [uri, setUri] = useState(null);
useEffect(() => {
(async () => {
const { uri } = props;
const name = shorthash.unique(uri);
const path = `${FileSystem.cacheDirectory}${name}`;
const image = await FileSystem.getInfoAsync(path);
if (image.exists) {
console.log("Read image from cache");
setUri(image.uri);
return;
} else {
console.log("Downloading image to cache");
const newImage = await FileSystem.downloadAsync(uri, path);
setUri(newImage.uri);
}
})();
}, []);
// Needs to have the final uri before render the image
return uri && <Component {...props} uri={uri} />;
};
Wrapped.propTypes = Component.propTypes;
return Wrapped;
};
export default withCache;