Обновление основного состояния внутри FlatList renderItem () - PullRequest
0 голосов
/ 05 апреля 2020

Я создаю своего рода приложение списка, я хочу, чтобы пользователь при нажатии на TouchableOpacity изменил состояние. State содержит количество раз, сколько раз нужно щелкнуть по атрибуту с именем repeat, например, если повторение равно (5). Я хочу, чтобы пользователь изменял значение click (4) и т. Д.

Я пробовал много вещей решить, но, к сожалению, ничего не работает Может кто-нибудь помочь?

import React, {useState, useEffect ,useCallback} from 'react';
import {View, 
    Text, 
    StyleSheet, 
    FlatList , 
    TouchableOpacity, 
    ImageBackground, 
    Dimensions,
} from 'react-native';
import Spacer from '../components/Spacer';
import Audio from '../components/Audio';
import myApi from '../APIs/myApi';



const SCREEN_WIDTH = Dimensions.get('window').width;
const SCREEN_HEIGHT = Dimensions.get('window').height;

const ShowScreen = ({ navigation }) => {

    const [text, setText] = useState({});
    const [repeat, setRepeat] = useState();

    const id = navigation.getParam('id');
    const title = navigation.getParam('title');    

    const Api = async() => {
        const response = await myApi.get(`/${id}`);
        setText(response.data);
    };


    useEffect(() => {
        Api();
    } , []);

    return (
        <View style={styles.container}>
        <Text style = {styles.textHead}> {title} </Text>
            <FlatList 
            data = {text.content}
            keyExtractor = {(text) => text.id}
            renderItem = {({item}) => {
                return (
                    <View style = {styles.listContainer}>
                        <TouchableOpacity onPress = {() => item.repeat = item.repeat - 1}>
                        <Text style= {styles.textList}> {item.text} </Text>
                        <Spacer />
                        <Audio  link = {item.audio_url} />
                        </TouchableOpacity>
                        <View style = {styles.repeatContianer} >
                            <Text> {item.repeat} </Text>
                        </View>
                    </View>
                );
            }}
            extraData = {text.repeat}
            />
        </View>
    );
};



const styles = StyleSheet.create({
    container : {
        flex : 1,
        alignItems : 'center',
        marginTop : 15,
    },
    textHead : {
        fontSize : 26,
        textDecorationLine : 'underline',
        fontWeight : 'bold'
    },
    textList : {
        fontSize : 20,
        fontStyle : 'italic',
        margin : 5,
        alignSelf: 'center',
        justifyContent : 'center',

    },
    listContainer : {
        borderWidth : 1  ,
        justifyContent : 'center',
        alignItems : 'center',
        margin : 5,
        borderRadius : 7
    },
    repeatContianer : {
        flex: 1,
        borderWidth : 1.5,
        borderRadius : 5,
        borderColor : 'red',
        margin : 5
    },
    backGround : {
        flex: 1,
        resizeMode: "cover",
        justifyContent: "center",
        width : SCREEN_WIDTH,
        height : SCREEN_HEIGHT,
        opacity : 0.4
    }
});


export default ShowScreen;

1 Ответ

0 голосов
/ 06 апреля 2020

Следует избегать мутаций, вместо записи item.repeat = item.repeat - 1 в onPress, вы должны поднять его на шаг вверх, ваш renderItem должен быть изменен на что-то вроде

renderItem = {({item, index}) => {
                return (
                    <View style = {styles.listContainer}>
                        <TouchableOpacity onPress = {() => _handleOnPress({item, index})}>
                        <Text style= {styles.textList}> {item.text} </Text>
                        <Spacer />
                        <Audio  link = {item.audio_url} />
                        </TouchableOpacity>
                        <View style = {styles.repeatContianer} >
                            <Text> {item.repeat} </Text>
                        </View>
                    </View>
                );
            }}

, чем в _handleOnPress Вы можете обновить свое состояние

_handleOnPress =({item, index})=>{
     //add necessary checks for current or index
     const contentCopy = text.content;   //created a copy
     const current = contentCopy[index]; 
     const updatedContent = [...contentCopy.slice(0, index), //finding and updating only current item
                      {...current, repeat:current.repeat-1}...contentCopy.slice(index+1)];
    setText({...text, content:updatedContent});

}

или создать свой renderItem как другой компонент и обрабатывать в нем обновление, что-то похожее на

const ListItem =({item, index})=>{
   const [repeat, setRepeat]= React.useState(item.repeat);

   return(
     <Your_UI_Goes_Here onPress={()=>{setRepeat(repeat-1)}}/>
   )
}
...