Home > OS >  How to prevent component to re-render every time?
How to prevent component to re-render every time?

Time:12-20

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

  • Related