React native - как установить это состояние с помощью хуков вместо this.state? - PullRequest
1 голос
/ 07 августа 2020

Хорошо, у меня есть Snack, который я пытаюсь преобразовать с использованием функциональных компонентов / хуков. Я новичок в logi c хуков и нуждаюсь в некоторой ясности.

Я использую эту библиотеку https://github.com/archriss/react-native-snap-carousel и настраиваю эффект следующим образом:

this.carouselRef= React.createRef();
    this.state = {
      activeIndex: 0,
      carouselItems: [
        {
          title: 'Item 1',
          text: 'Text 1',
        },
        {
          title: 'Item 2',
          text: 'Text 2',
        },
        {
          title: 'Item 3',
          text: 'Text 3',
        },
        {
          title: 'Item 4',
          text: 'Text 4',
        },
        {
          title: 'Item 5',
          text: 'Text 5',
        },
      ],
    };
  }

  _onPressCarousel = (index) => {
    // here handle carousel press
    this.carouselRef.current.snapToItem(index);
  };

  _renderItem = ({ item, index }) => {
    return (
      <TouchableOpacity
        onPress={() => {
          this._onPressCarousel(index);
        }}
        style={{
          backgroundColor: 'white',
          borderRadius: 20,
          height: 300,
          padding: 50,
        }}>
        <Text style={{ fontSize: 30 }}>{item.title}</Text>
        <Text>{item.text}</Text>
      </TouchableOpacity>
    );
  };

Вы можете посмотреть, как работает закуска здесь https://snack.expo.io/@skyyguy1999 / jealous-scone

Это было написано для настройки export default class App, однако мое приложение структурировано, начиная с export default function App()

Как я могу установить вышеуказанные состояния с помощью хуков? то есть вместо this.state = это был бы какой-то синтаксис, например const carouselState =

EDIT:

Теперь я получаю ошибку

prop 'data' помечен как требуется в 'Карусель', но его значение не определено

со следующими изменениями:

const carouselRef = React.createRef();
  const [carouselState, setCarouselState] = useState({
      activeIndex: 0,
      carouselItems: [
        {
          title: 'Item 1',
          text: 'Text 1',
        },
        {
          title: 'Item 2',
          text: 'Text 2',
        },
        {
          title: 'Item 3',
          text: 'Text 3',
        },
        {
          title: 'Item 4',
          text: 'Text 4',
        },
        {
          title: 'Item 5',
          text: 'Text 5',
        },
      ],
    });

const onPressCarousel = (index) => {
    // here handle carousel press
    carouselRef.current.snapToItem(index);
  };

  const renderItem = ({ item, index }) => {
    return (
      <TouchableOpacity
        onPress={() => {
          onPressCarousel(index);
        }}
        style={{
          backgroundColor: 'white',
          borderRadius: 20,
          height: 300,
          padding: 50,
        }}>
        <Text style={{ fontSize: 30 }}>{item.title}</Text>
        <Text>{item.text}</Text>
      </TouchableOpacity>
    );
  };

<SafeAreaView
                style={{ flex: 1, backgroundColor: 'rebeccapurple', paddingTop: 50 }}>
                <View
                  style={{ flex: 1, flexDirection: 'row', justifyContent: 'center' }}>
                  <Carousel
                    layout={'default'}
                    ref={carouselRef}
                    data={carouselState.carouselItems}
                    sliderWidth={SliderWidth}
                    itemWidth={300}
                    renderItem={renderItem}
                    useScrollView
                    onSnapToItem={(index) => setCarouselState({ activeIndex: index })}
                    activeSlideAlignment="center"
                  />
                </View>
              </SafeAreaView>

Ответы [ 2 ]

1 голос
/ 07 августа 2020

Вот пример вашего кода с реализацией хуков,

import React, { useState, useEffect } from 'react';
import {
  Text,
  View,
  SafeAreaView,
  Dimensions,
  TouchableOpacity,
} from 'react-native';

import Carousel from 'react-native-snap-carousel';

const SliderWidth = Dimensions.get('screen').width;

export default function App() {
  const [activeIndex, setActivateIndex] = useState(0); 
  const [carouselState, setCarouselState] = useState([
        {
          title: 'Item 1',
          text: 'Text 1',
        },
        {
          title: 'Item 2',
          text: 'Text 2',
        },
        {
          title: 'Item 3',
          text: 'Text 3',
        },
        {
          title: 'Item 4',
          text: 'Text 4',
        },
        {
          title: 'Item 5',
          text: 'Text 5',
        },
      ],
    );

  const _onPressCarousel = (index) => {
    // here handle carousel press
    this.carouselRef.current.snapToItem(index);
  };

  const _renderItem = ({ item, index }) => {
    return (
      <TouchableOpacity
        onPress={() => {
          this._onPressCarousel(index);
        }}
        style={{
          backgroundColor: 'white',
          borderRadius: 20,
          height: 300,
          padding: 50,
        }}>
        <Text style={{ fontSize: 30 }}>{item.title}</Text>
        <Text>{item.text}</Text>
      </TouchableOpacity>
    );
  };

  return (
    <SafeAreaView
      style={{ flex: 1, backgroundColor: 'rebeccapurple', paddingTop: 50 }}>
      <View
        style={{ flex: 1, flexDirection: 'row', justifyContent: 'center' }}>
        <Carousel
          layout={'default'}
          ref={this.carouselRef}
          data={carouselState}
          sliderWidth={SliderWidth}
          itemWidth={300}
          renderItem={this._renderItem}
          useScrollView
          onSnapToItem={(index) => setActivateIndex(index)}
          activeSlideAlignment="center"
        />
      </View>
    </SafeAreaView>
  );
  
}

Вам не нужно объявлять все переменные состояния в одном объявлении. Вы можете разделить их на части и использовать и управлять отдельно.

надеюсь, что это сработает.

0 голосов
/ 07 августа 2020

Используйте хук useState , например

const [activeIndex, setActiveIndex] = useState(0);
...