首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >FlatList在数据更改后未正确显示数据

FlatList在数据更改后未正确显示数据
EN

Stack Overflow用户
提问于 2020-11-27 12:39:08
回答 2查看 87关注 0票数 0

我从数据库中获取数据并在FlatList中显示。每当我从数据中添加或删除某些内容时,数据在FlatList中就不会正确显示。每当我删除某些内容时,它都会显示一个空列表。每当我添加某项内容时,它只显示新添加的数据--没有其他数据。

我正在使用firebase实时数据库,并使用所获得的数据如下:

代码语言:javascript
复制
firebase.database().ref(`/wordlists/${editKey}`).on('value', snap => {
    if (snap.val() !== null) {
        setIsLoading(false);
        const val = snap.val().words;
        const data = [];
        Object.keys(val).forEach(key => {
            data.push({ key, word: val[key].word });
        })
        setWords(data);
        // setWords([...data]) doesn't work either.
    }
}) 

我的Flatlist是这样的:

代码语言:javascript
复制
<FlatList 
    data={words}
    renderItem={renderItem}
    keyExtractor={item => item.key}
    extraData={words}
/>

当我console.log()数据时,我总是得到我想要显示的数据,但是FlatList就是不能正确地显示它。

当我使用散列运算符和/或extraData时,它也不起作用。

因为有人在这里要求它是整个文件(我忽略了样式和导入)

代码语言:javascript
复制
const EditList = ({ editKey }) => {

    const [wordlist, setWordlist] = useState(0);
    const [refresh, setRefresh] = useState(false);
    const [words, setWords] = useState([]);
    const [wordLoading, setWordLoading] = useState({ loading: false });
    const [loading, setIsLoading] = useState(false);
    const [btnLoading, setBtnLoading] = useState(false);
    const [word, setWord] = useState('');

    useEffect(() => {
        if (editKey !== 0) {
            setIsLoading(true);
            firebase.database().ref(`/wordlists/${editKey}`).on('value', snap => {
                if (snap.val() !== null) {
                    setIsLoading(false);
                    setWordlist({...snap.val()});
                    const val = snap.val().words;
                    const data = [];
                    Object.keys(val).forEach(key => {
                        data.push({ key, word: val[key].word });
                    })
                    setWords([...data]);
                    setRefresh(!refresh);
                    console.log(data, 'DATA');
                }
            })
        }
    }, [editKey])

    const onAdd = () => {
        setBtnLoading(true);
        firebase.database().ref(`/wordlists/${editKey}/words`).push({ word })
        .then(() => {
            setBtnLoading(false);
            setWord('');
            setRefresh(!refresh);
        })
    }

    const onDelete = (key) => {
        setWordLoading({ key, loading: true });
        firebase.database().ref(`/wordlists/${editKey}/words/${key}`).remove().then(() => {
            setWordLoading({ loading: false });
            setRefresh(!refresh);
        });
    }

    const renderItem = ({ item }) => (
        <ItemWrapper>
            <ItemWord>{ item.word }</ItemWord>
            <DeleteView onPress={() => onDelete(item.key)}>
                { wordLoading.loading && wordLoading.key === item.key ?
                    <ActivityIndicator size="small" /> :
                    <DIcon name="trash-2" size={24} />
                }
            </DeleteView>
        </ItemWrapper>
    )

    const createData = (words) => {
        const data = [];
        if (typeof words !== 'undefined') {
            Object.keys(words).forEach(key => {
                const obj = { key, word: words[key].word };
                data.push(obj);
            })
        }
        console.log(data, 'DATADATADATA');
        return data;
    }

    if (editKey === 0) {
        return (
            <NokeyWrapper>
                <NoKeyText>No list selected...</NoKeyText>
            </NokeyWrapper>
        )
    }
    if (loading) {
        return (
            <NokeyWrapper>
                <ActivityIndicator size="large" />
            </NokeyWrapper>
        )
    }
    return (
        <Wrapper 
            behavior={Platform.OS == "ios" ? "padding" : "height"} 
            keyboardVerticalOffset={Platform.OS === 'ios' && 180}
        >
            <WordListName>{wordlist.listName}</WordListName>
            <FlatListWrapper>
                <FlatList 
                    data={words}
                    renderItem={renderItem}
                    keyExtractor={item => item.key}
                    //extraData={refresh}
                    extraData={words}
                />
            </FlatListWrapper>
            <AddWordWrapper>
                <SInput value={word} onChangeText={(text) => setWord(text)} />
                <Button onPress={() => onAdd()} loading={btnLoading}>
                    <Feather name="plus" size={24} color="black" />
                </Button>
            </AddWordWrapper>
        </Wrapper>
    )
};

export default EditList;

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2020-12-02 23:08:11

经过多次尝试,我发现问题出在别的地方。不知何故,在我的renderItem()中使用'flex: 1‘是造成这个问题的原因。实际上,我在github:GitHub对本地问题作出反应上也发现了这个问题。

因此,在从元素中移除“flex:1”之后,一切都如期而至。

代码语言:javascript
复制
// before
const renderItem = ({ item }) => (
    <ItemWrapper style={{ flex: 1, flexDirection: row }}>
        <ItemWord>{ item.word }</ItemWord>
    </ItemWrapper>
)

// after
const renderItem = ({ item }) => (
    <ItemWrapper style={{ width: '100%' }}>
        <ItemWord>{ item.word }</ItemWord>
    </ItemWrapper>
)
票数 0
EN

Stack Overflow用户

发布于 2020-11-27 17:50:12

对于这个实例,您需要useRef,因为新的'words‘不在.on('value')调用中。

代码语言:javascript
复制
 const [words, _setWords] = useState([]);
 const wordRef = useRef(words)


 //function to update both wordRef and words state
 const setWords = (word) => {
        
      wordRef = word
      _setWords(word)
 } 



useEffect(() => {

if (editKey !== 0) {
    setIsLoading(true);
    let data = wordRef   //create a temp data variable
    firebase.database().ref(`/wordlists/${editKey}`).on('value', snap => {
        if (snap.val() !== null) {
            setIsLoading(false);                 
            setWordlist({...snap.val()});
            const val = snap.val().words;

            Object.keys(val).forEach(key => {
                data.push({ key, word: val[key].word });
            })
            setWords(data);
            setRefresh(!refresh);
            console.log(data, 'DATA');
        }
    })

    return () => firebase.database().ref(`/wordlists/${editKey}`).off('value') // <-- need to turn it off.
}
}, [editKey, wordRef])

您可能需要用相同的方法更改setRefresh等,如果它们不是刷新的话。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/65037526

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档