Expo SDK 29 FlatList onRefresh не звонит - PullRequest
0 голосов
/ 21 сентября 2018

Использование Expo SDK 29 для собственного приложения реакции.

Я хотел бы использовать компонент плоского списка.Это составляет весь компонент SafeAreaView.Я подчеркиваю это, поскольку существует много проблем, связанных с плоским списком в представлении прокрутки, но это не так.

Плоский список показывает список заданий.

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

Когда я добавляю реквизиты в плоский списокдля onRefresh и обновления компонент, кажется, работает, показывая индикатор активности в пользовательском интерфейсе, но не запускает функцию onRefresh.Я пытался реализовать вызов множеством способов, но ничего не происходит.В результате индикатор активности показывает себя и никогда не исчезает.

Так как это версия Expo SDK 29, версия React Native - 0.55.4

У всех есть идеи, что попробовать.Я потратил пару часов на то, чтобы попробовать разные вещи, но предложения приветствуются.

Заранее спасибо.

РЕДАКТИРОВАТЬ: Добавлен код для справки.Редуктор для обновления устанавливает значение true, когда fetchJobs () отправляется, и значение false, если получен успех или ошибка.Журнал консоли для onRefresh никогда не запускается.

import * as React from 'react'
import * as actions from '../../redux/actions'
import { ActivityIndicator, FlatList, KeyboardAvoidingView, Dimensions, SafeAreaView, StyleSheet, View } from 'react-native'
import { ApplicationState, JobState, Job } from '../../redux'
import { Button, Form, Input, Item, Text, Icon } from 'native-base'
import { JobListItem } from './jobListItem'
import { StateHandlerMap, compose, lifecycle, withPropsOnChange, withStateHandlers } from 'recompose'
import { connect } from 'react-redux'

interface ReduxStateProps {
    jobs: JobState
    refreshing: boolean
    screenOrientation: string
}

interface ReduxDispatchProps {
    fetchJobs: (param?: string) => any
}

export interface DataItem {
    key: string
    data: Job
}

interface ListProps {
    jobList: DataItem[]
}

interface SearchStateProps {
    timer: number | undefined
    searchString: string
}

interface SearchHandlerProps extends StateHandlerMap<SearchStateProps> {
    updateSearch: (searchString: string) => any
    setTimer: (timer: number | undefined) => any
}

type OuterProps = {}
type InnerProps = OuterProps & ReduxStateProps & ReduxDispatchProps & ListProps & SearchStateProps & SearchHandlerProps

const enhance = compose<InnerProps, OuterProps>(
    connect<ReduxStateProps, ReduxDispatchProps, OuterProps, ApplicationState>(
        state => ({
            jobs: state.job,
            refreshing: state.jobLoading,
            screenOrientation: state.screenOrientation
        }),
        dispatch => ({
            fetchJobs: (param?: string) => dispatch(actions.jobs.request({ param }))
        })
    ),
    withPropsOnChange<ListProps, OuterProps & ReduxStateProps & ReduxDispatchProps>(
        ['jobs', 'screenOrientation'],
        props => ({
            jobList: props.jobs && Object.keys(props.jobs).map(job => ({ key: job, data: props.jobs[Number(job)] }))
        })
    ),
    withStateHandlers<SearchStateProps, SearchHandlerProps, OuterProps>(
        {
            timer: undefined,
            searchString: ''
        },
        {
            updateSearch: state => (searchString: string) => ({ searchString }),
            setTimer: state => (timer: number | undefined) => ({ timer })
        }
    ),
    lifecycle<InnerProps, {}>({
        componentDidMount() {
            this.props.fetchJobs()
        }
    })
)

export const JobList = enhance(({ fetchJobs, jobList, refreshing, screenOrientation, searchString, setTimer, timer, updateSearch }) => {

    const onSearchChange = (search: string) => {
        clearTimeout(timer)

        updateSearch(search)

        const timing = setTimeout(() => {
            fetchJobs(search)
        }, 500)

        setTimer(timing)
    }
const onRefresh = () => {
    console.log('requesting refresh')
    fetchJobs()
}

return (
    <SafeAreaView style={{ flex: 1}}>
        <KeyboardAvoidingView style={{ flexDirection: 'row', justifyContent: 'space-evenly', paddingTop: 3, paddingRight: 3 }}>
            <Form style={{ flex: 1, paddingLeft: 10, paddingRight: 10 }}>
                <Item>
                    <Input
                        value={searchString}
                        onChangeText={(text: string) => onSearchChange(text)}
                        placeholder='Search' 
                    />
                </Item>
            </Form>
            <Button onPress={() => {fetchJobs(); updateSearch('')}}>
                <Icon name='refresh' />
            </Button>
        </KeyboardAvoidingView>

        {refreshing && 
            <View style={styles.refreshContainer}>
                <Text style={{ paddingBottom: 10 }}>Fetching Data</Text>
                <ActivityIndicator />
            </View>
        }
        <FlatList
            keyExtractor={item => item.key} 
            data={jobList}
            renderItem={({ item }) => 
                <JobListItem 
                    screenOrientation={screenOrientation}
                    item={item}
                />
            }
            onRefresh={onRefresh}
            refreshing={refreshing}
        />
    </SafeAreaView>
)
})

const styles = StyleSheet.create({
    refreshContainer: {
        height: 60,
        flex: 1,
        flexDirection: 'column',
        justifyContent: 'center',
        alignItems: 'center'
    }
})

1 Ответ

0 голосов
/ 03 октября 2018

У меня точно такая же проблема, и я использую expo SDK 30. Но мой случай немного отличается.Функция onRefresh вызывается каждый раз, когда я вытягиваюсь, однако, если я прокручиваю свой список вниз и быстро возвращаюсь назад, появляется индикатор загрузки, но моя функция onRefresh не вызывается.

Моя обновляющая реквизит установлена ​​на моемreducer, и моя функция onRefresh отправляет действие, которое извлекает данные и устанавливает обновление true и false.

Вот мой код:

    class NoticiasScreen extends Component {
  static navigationOptions = {
    header: <Header
              title='Notícias Alego'
              leftComponent={<Image source={require('../../../assets/images/play_grande.png')} style={imageStyle} resizeMode='contain'/>}
            />
  }

  constructor(props) {
    super(props);

    this.renderItem = this.renderItem.bind(this);
    this.keyExtractor = this.keyExtractor.bind(this);
    this.renderContent = this.renderContent.bind(this);
    this.navigateToNoticias = this.navigateToNoticias.bind(this);
    this.carregarMaisNoticias = this.carregarMaisNoticias.bind(this);
    this.onRefresh = this.onRefresh.bind(this);
  }

  componentDidMount() {
    this.props.carregarNoticias(this.props.pagina);
  }

  renderItem({item}) {
    return (
      <NoticiaListItem noticia={item} abrirNoticia={this.navigateToNoticias} />
    );
  }

  keyExtractor(item) {
    return item.id.toString();
  }

  navigateToNoticias(noticia) {
    this.props.navigation.navigate('NoticiasExibir', { id: noticia.id });
  }

  onRefresh() {
    console.log('onRfresh');
    this.props.carregarNoticias(1, true);
  }

  carregarMaisNoticias() {
    const { carregarNoticias, pagina } = this.props;
    carregarNoticias(pagina + 1);
  }

  renderContent() {
    const { noticias, carregandoNoticias, erroNoticias } = this.props;

    if(noticias.length === 0 && carregandoNoticias) {
      return (
        <View style={styles.containerCenter}>
          <ActivityIndicator size="large" color={colors.verde}/>
        </View>
      );
    }

    if(erroNoticias) {
      return (
        <View style={styles.containerCenter}>
          <Text style={styles.message}>{erroNoticias}</Text>
          <TouchableOpacity hitSlop={hitSlop15}>
            <Text>Recarregar</Text>
          </TouchableOpacity>
        </View>
      )
    }

    return (
      [<TextInput
        style={styles.textInput}
        placeholder='Pesquise'
        key='pesquisa'
        underlineColorAndroid='transparent'
      />,
      <FlatList
        data={noticias}
        renderItem={this.renderItem}
        keyExtractor={this.keyExtractor}
        style={styles.list}
        key='lista'
        onRefresh={this.onRefresh}
        refreshing={carregandoNoticias}
        onEndReached={this.carregarMaisNoticias}
        onEndReachedThreshold={0.1}
      />]
    )
  }

  render() {
    return (
      <SafeAreaView style={styles.safeArea}>
        <View style={styles.container}>

          {this.renderContent()}
        </View>
      </SafeAreaView>
    );
  }
}

function mapStateToProps(state) {
  return {
    noticias: state.intranet.noticias,
    pagina: state.intranet.pagina,
    erroNoticias: state.intranet.erroNoticias,
    carregandoNoticias: state.intranet.carregandoNoticias
  }
}

function mapDispatchToProps(dispatch) {
  return {
    carregarNoticias: (pagina, recarregar) => dispatch(ActionCreator.carregarNoticias(pagina, recarregar))
  }
}

export default connect(mapStateToProps, mapDispatchToProps)(NoticiasScreen);

Понятия не имею, что происходит.Любая помощь приветствуется.

РЕДАКТИРОВАТЬ:

Я как-то исправил.Я добавил реквизит onMomentScrollBegin, чтобы предотвратить рендеринг моего flatList дважды при рендеринге, и это исправило эту проблему.

вот что я добавил:

 constructor(props) {
    super(props);

    ...

    this.onRefresh = this.onRefresh.bind(this);


    this.onMomentumScrollBegin = this.onMomentumScrollBegin.bind(this);

    this.onEndReachedCalledDuringMomentum = true; //PUT THIS HERE
  }


 onRefresh() {
    this.props.carregarNoticias(1, true);
  }

  carregarMaisNoticias() {
    if(!this.onEndReachedCalledDuringMomentum){
      const { carregarNoticias, pagina } = this.props;
      carregarNoticias(pagina + 1);
      this.onEndReachedCalledDuringMomentum = true;
    }
  }

  onMomentumScrollBegin() {
    this.onEndReachedCalledDuringMomentum = false;
  }

render() {
  <OptimizedFlatList
    data={noticias}
    renderItem={this.renderItem}
    keyExtractor={this.keyExtractor}
    style={styles.list}
    key='lista'
    onRefresh={this.onRefresh}
    refreshing={carregandoNoticias}
    onMomentumScrollBegin={this.onMomentumScrollBegin} //PUT THIS HERE
    onEndReached={this.carregarMaisNoticias}
    onEndReachedThreshold={0.1}
 />
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...