I have a custom component where I want to prevent the useEffect
to fire every time the component is rendering.
The main idea is to get the font-family name from the API and then pass it to the style value, so I want to get the font family just once - not every time the component renders in other screens.
Here's what I tried, but it doesn't work as expected, it's not updating the state after getting the value from API (getValue()
not called).
import React, {useCallback, useEffect, useRef} from 'react';
import {useState} from 'react';
import {Text, StyleSheet, Platform} from 'react-native';
import {COLORS} from '../../common';
const AppText = ({children, style, ...rest}) => {
const isMounted = useRef(false);
const [fontFamily, setFontFamily] = useState('Helvetica-Bold');
const getValue = useCallback(() => {
// mock API
setTimeout(() => {
console.log('AppText: get font family name from API!!');
setFontFamily('HelveticaNeue');
}, 200);
}, []);
useEffect(() => {
if (isMounted.current) {
getValue();
} else {
isMounted.current = true;
return;
}
}, [getValue]);
return (
<Text
style={[
styles.text,
style,
{
fontFamily: fontFamily,
},
]}
{...rest}>
{children}
</Text>
);
};
export {AppText};
using:
Home/About/etc // other screens
const Home = () => {
return(
<View>
<AppText> Hey from home </AppText>
</View>
);
}
CodePudding user response:
You can use a context to propergate the value down into multiple components (or use props) and just fetch it once higher up in the tree.
//App.js
import {useEffect, createContext, useState} from "react";
export const FontFamilyContext = createContext("DefaultFont");
const App = () =>{
const [font,setFont] = useState();
useEffect( () =>{
setFont(loadFont());
},[]);
return (
<FontFamilyContext.Provider value={font} >
<Screen />
<ScreenViaProp fontFamily={font} />
</FontFamilyContext.Provider>
);
}
export default App;
//Screen.jsx
//Advantage The font family can be used in nested components deep down
import { useContext } from "react";
import {FontContext} from "./App";
const Screen = () =>{
const fontFamily = useContext(FontFamilyContext);
return (
<div style={{fontFamily: fontFamily}}>
</div>
)
}
// ScreenViaProp .jsx Easier and no context is required
const ScreenViaProp = ({fontFamily}) =>{
return (
<div style={{fontFamily: fontFamily}}>
</div>
)
}
CodePudding user response:
use e.preventDefault(); in submit Handler