React Native - использование хуков с render () - PullRequest
0 голосов
/ 08 июля 2020

Я пытаюсь использовать шрифт (шрифты Google) в собственном приложении React. У меня проблема с перехватчиком:

const [fontsLoaded ,setFontsLoaded] = useState(false);

Я считаю, что проблема связана с опорой render (). Может ли кто-нибудь посоветовать мне, где я должен добавить приведенный выше код, чтобы получить этот woking?

Мой код:

import React, { Component, useState } from 'react';
import * as Font from 'expo-font';
import { StyleSheet, Text, View } from 'react-native';
import { AppLoading } from 'expo';

 const getFonts = () => Font.loadAsync({
    'lobster': require('./assets/fonts/Lobster-Regular.ttf')
    });

export default class App extends Component {  
  render() {
    const [fontsLoaded ,setFontsLoaded] = useState(false);
    const gradientHeight=500;
    const gradientBackground  = '#12C1E5';
    const data = Array.from({ length: gradientHeight });

    if(fontsLoaded){
      return (
        <View style={styles.container}>    
          <View style={styles.centering}>
            <Text style={styles.titleText}>Test Title</Text>
          </View> 
          <View style={{flex:1}}>
            {data.map((_, i) => (
              <View
                key={i}
                style={{
                  position: 'absolute',
                  backgroundColor: gradientBackground,
                  height: 1,
                  bottom: (gradientHeight - i),
                  right: 0,
                  left: 0,
                  zIndex: 2,
                  opacity: (1 / gradientHeight) * (i + 2)
                }}
              >
              </View>
            ))}      
          </View>
        </View>
      );
    } else {
      return (
        <AppLoading
          startAsync={getFonts}
          onFinish={() => setFontsLoaded(true)}
        />
      );
    }
  }
}

const styles = StyleSheet.create({
  container: {
    flex: 1,
    backgroundColor: '#0e99b5',
    },
  centering: {
    flex: 1,
    alignItems: 'center',
    justifyContent: 'center',
  },
  titleText: {
    color: 'orange',
    fontSize: 40,
  }
});

Я получаю ошибку:

Error: Invalid hook call.

Я просто пытаюсь использовать собственный шрифт и проверять, загружен ли шрифт перед рендерингом на экран.

1 Ответ

1 голос
/ 09 июля 2020

Вы не можете использовать ловушки внутри компонента класса. Хуки введены React для использования в функциональных компонентах. Таким образом, у вас есть два варианта:

  • использовать setState в вашем текущем компоненте класса ИЛИ
  • преобразовать ваш компонент класса в функциональный компонент.

Я предлагаю вам go с функциональным компонентом, поскольку вы не используете какие-либо жизненные циклы компонента класса.

Если вы go с первым подходом, вы можете изменить свой код, как показано ниже: -

export default class App extends Component { 
  state = {
    fontsLoaded: false,
  };

  updateFontsLoadedState = () => {
    this.setState({ fontsLoaded: true });
  }


  render() {
    const { fontsLoaded } = this.state;
    const gradientHeight=500;
    const gradientBackground  = '#12C1E5';
    const data = Array.from({ length: gradientHeight });

    if(fontsLoaded){
      return (
        <View style={styles.container}>    
          <View style={styles.centering}>
            <Text style={styles.titleText}>Test Title</Text>
          </View> 
          <View style={{flex:1}}>
            {data.map((_, i) => (
              <View
                key={i}
                style={{
                  position: 'absolute',
                  backgroundColor: gradientBackground,
                  height: 1,
                  bottom: (gradientHeight - i),
                  right: 0,
                  left: 0,
                  zIndex: 2,
                  opacity: (1 / gradientHeight) * (i + 2)
                }}
              >
              </View>
            ))}      
          </View>
        </View>
      );
    } else {
      return (
        <AppLoading
          startAsync={getFonts}
          onFinish={this.updateFontsLoadedState}
        />
      );
    }
  }
}

Если вы хотите использовать лучший подход, используйте хуки и преобразовать это в функциональный компонент, тогда вы можете сделать это, как показано ниже: -

export default function App(props) {
    const [fontsLoaded ,setFontsLoaded] = useState(false);
    const gradientHeight=500;
    const gradientBackground  = '#12C1E5';
    const data = Array.from({ length: gradientHeight });

    if(fontsLoaded){
      return (
        <View style={styles.container}>    
          <View style={styles.centering}>
            <Text style={styles.titleText}>Test Title</Text>
          </View> 
          <View style={{flex:1}}>
            {data.map((_, i) => (
              <View
                key={i}
                style={{
                  position: 'absolute',
                  backgroundColor: gradientBackground,
                  height: 1,
                  bottom: (gradientHeight - i),
                  right: 0,
                  left: 0,
                  zIndex: 2,
                  opacity: (1 / gradientHeight) * (i + 2)
                }}
              >
              </View>
            ))}      
          </View>
        </View>
      );
    } else {
      return (
        <AppLoading
          startAsync={getFonts}
          onFinish={() => setFontsLoaded(true)}
        />
      );
    }
}
...