简体   繁体   English

数据更改后 FlatList 无法正确显示数据

[英]FlatList not showing data correctly after data changes

I'm getting the data from the database and show it in a FlatList.我正在从数据库中获取数据并将其显示在 FlatList 中。 Whenever I add or remove something from the data the data isn't showing correctly in the FlatList.每当我从数据中添加或删除某些内容时,FlatList 中的数据都不会正确显示。 Whenever I remove something it shows an empty list.每当我删除某些东西时,它都会显示一个空列表。 Whenever I add something it only shows the newly added data - nothing else.每当我添加一些东西时,它只会显示新添加的数据——没有别的。 左:初始,中:新添加,右:数据已删除

I'm using firebase realtime database and use the data I get as follows:我正在使用 firebase 实时数据库并使用我得到的数据如下:

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.
    }
}) 

My Flatlist looks like this:我的平面列表如下所示:

<FlatList 
    data={words}
    renderItem={renderItem}
    keyExtractor={item => item.key}
    extraData={words}
/>

When I console.log() the data I always get the data I want to show but the FlatList just won't show it correctly.当我 console.log() 数据时,我总是得到我想要显示的数据,但 FlatList 只是无法正确显示。

It also doesn't work when I use the spread-operator and/or extraData.当我使用扩展运算符和/或 extraData 时,它也不起作用。

Because someone asked for it here is the entire file (I left out the styling and the imports)因为有人在这里要求它是整个文件(我省略了样式和导入)

 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;

u need to useRef for this instance because the new 'words' is not inside the.on('value') call.您需要为此实例使用 useRef,因为新的“单词”不在 .on('value') 调用中。

 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])

You probably need to change setRefresh etc with the same method if they are not refreshing.如果不刷新,您可能需要使用相同的方法更改 setRefresh 等。

After a lot more tries I found out the problem was somewhere else.经过多次尝试,我发现问题出在其他地方。 Somehow using 'flex: 1' on my in my renderItem() was causing this issue.在我的 renderItem() 中以某种方式使用 'flex: 1' 导致了这个问题。 I actually found this issue also on github: GitHub React Native issues我实际上也在 github 上发现了这个问题: GitHub React Native issues

So after removing 'flex: 1' from the element everything was showing as expected.因此,从元素中删除 'flex: 1' 后,一切都按预期显示。

// 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>
)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM