react native: как можно изменить компонент класса на функциональный компонент и хуки?

#javascript #reactjs #react-native #react-hooks

#javascript #reactjs #react-native #реагирующие перехваты

Вопрос:

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

 export default class AzureLogin extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      azureLoginObject: {},
      loginSuccess: false,
      loading: true,
    };
    this.azureInstance = new AzureInstance(credentials);
    this._onLoginSuccess = this._onLoginSuccess.bind(this);
  }

  async componentDidMount() {
    const firstTime = await AsyncStorage.getItem('AZURE-TOKEN');
    if (firstTime != null) {
      this.props.navigation.dispatch(StackActions.replace('דגימות איכות מים'));
    } else {
      this.setState({ loginSuccess: firstTime != null, loading: false });
    }
  }

  _onLoginSuccess() {
    this.azureInstance
      .getUserInfo()
      .then(async (result) => {
        console.log(result);
        //HERE EXAMPLE FOR STORE SOME VARIABLE INTO MY REDUX STORE
        store.dispatch(userPrincipalName(result.userPrincipalName));
        store.dispatch(givenName(result.mobilePhone));
        ///THIS IS AZURE TOKEN
        // console.log('AZURE-TOKEN', JSON.stringify(this.azureInstance.token));

        ///SAVE AZURE-TOKEN INTO AsyncStorage
        await AsyncStorage.setItem(
          'AZURE-TOKEN',
          JSON.stringify(this.azureInstance.token)
        );
        ///SAVE AZURE-USERNAME INTO AsyncStorage
        await AsyncStorage.setItem(
          'AZURE-USERNAME',
          result.userPrincipalName.split('@')[0]
        );

        this.setState({
          loginSuccess: true,
          azureLoginObject: result,
        });
        this.props.navigation.dispatch(
          StackActions.replace('דגימות איכות מים')
        );
      })
      .catch((err) => {
        console.log(err);
      });
  }

  render() {
    if (!this.state.loading)
      return (
        <AzureLoginView
          azureInstance={this.azureInstance}
          loadingMessage="Requesting access token"
          onSuccess={this._onLoginSuccess}
        />
      );
    return <ActivityIndicator />;
  }
}
  

Комментарии:

1. Пожалуйста, ознакомьтесь с этим руководством, оно может оказаться полезным nimblewebdeveloper.com/blog /…

2. я попробовал, но также получил некоторые ошибки, можете ли вы помочь мне преобразовать его?

3. Что вы пробовали (здесь рассматривается попытка поделиться) и каковы ошибки (опять же, вопрос об обновлении и совместном использовании)?

4. я делаю салат в своем коде, пытаясь изменить его на функциональный компонент, поэтому я не могу поделиться им, потому что там все сделано не очень хорошо.

Ответ №1:

Попробуйте выполнить следующие шаги.

  1. Преобразовать состояние в useState перехваты реакции. Вы также можете использовать инициализатор функции для сохранения нового AzureInstance в состоянии. Вы также можете использовать ссылку.
  2. Преобразовать componentDidMount в useEffect с пустым массивом зависимостей. Создайте внутреннюю асинхронную функцию и вызовите.
  3. Преобразуйте все ссылки this в новую ссылку без экземпляра (в основном просто удаляйте this из всего).
  4. Деструктура передала реквизиты в сигнатуре функции

Следующее должно приблизить вас.

Код:

 const AzureLogin = ({ navigation }) => {
  const [azureInstance] = useState(() => new AzureInstance(credentials));
  const [azureLoginObject, setAzureLoginObject] = useState({});
  const [loginSuccess, setLoginSuccess] = useState(false);
  const [loading, setLoading] = useState(true);

  useEffect(() => {
    const loadData = async () => {
      const firstTime = await AsyncStorage.getItem('AZURE-TOKEN');

      if (firstTime) {
        navigation.dispatch(StackActions.replace('דגימות איכות מים'));
      } else {
        setLoginSuccess(firsTime !== null);
        setLoading(false);
      }
    };

    loadData();
  }, []);

  const _onLoginSuccess = () => {
    azureInstance
      .getUserInfo()
      .then(async (result) => {
        console.log(result);
        //HERE EXAMPLE FOR STORE SOME VARIABLE INTO MY REDUX STORE
        store.dispatch(userPrincipalName(result.userPrincipalName));
        store.dispatch(givenName(result.mobilePhone));
        ///THIS IS AZURE TOKEN
        // console.log('AZURE-TOKEN', JSON.stringify(azureInstance.token));

        ///SAVE AZURE-TOKEN INTO AsyncStorage
        await AsyncStorage.setItem(
          'AZURE-TOKEN',
          JSON.stringify(azureInstance.token)
        );
        ///SAVE AZURE-USERNAME INTO AsyncStorage
        await AsyncStorage.setItem(
          'AZURE-USERNAME',
          result.userPrincipalName.split('@')[0]
        );

        setLoginSuccess(true);
        setAzureLoginObject(result);

        navigation.dispatch(
          StackActions.replace('דגימות איכות מים')
        );
      })
      .catch((err) => {
        console.log(err);
      });
  }

  return loading ? (
    <ActivityIndicator />
  ) : (
    <AzureLoginView
      azureInstance={azureInstance}
      loadingMessage="Requesting access token"
      onSuccess={_onLoginSuccess}
    />
  );
}