简体   繁体   English

使用 extraData 在功能组件中重新渲染平面列表时遇到问题

[英]Trouble re-rendering flatlist in functional component using extraData

I'm struggling to re-render a flatlist.我正在努力重新渲染平面列表。 I'm trying to use a boolean refreshToggle , that is fed into extraData , that is changed after the desired information is successfully fetched.我正在尝试使用 boolean refreshToggle ,它被输入到extraData ,在成功获取所需信息后更改。 The code below successfully fetches the data and changes the boolean (so changing to functional updates for the state, while perhaps better practice, doesn't seem like a solution) (I've checked that this is happening with various logs etc), but the flatlist doesn't re-render.下面的代码成功获取数据并更改了 boolean(因此更改为 state 的功能更新,虽然可能是更好的做法,但似乎不是一个解决方案)(我已经检查过各种日志等是否发生这种情况),但是平面列表不会重新呈现。

export default function transactions({ navigation }: { navigation: any }) {
    const [paymentsBtnActive, setPaymentsBtnActive] = React.useState<boolean>(navigation.getParam('Pressed') == 'Payments');
    const [requestsBtnActive, setRequestsBtnActive] = React.useState<boolean>(navigation.getParam('Pressed') == 'Requests');
    const [refreshToggle, setRefreshToggle] = React.useState<boolean>(false);

    let data: any[] = [];

    async function getRequests() {
        const body = { 
            'phone': GLOBAL.userInfo['phone']
        }
        const options = {
            method: 'POST',
            headers: { 'Content-Type': 'application/json'},
            body: JSON.stringify(body)
        }
        let requests =  await fetch('http://3ef68e9c1352.ngrok.io/requests/user', options);
        let requestsJSON = await requests.json();
        data = requestsJSON['data'];
    }    

    function renderItem(item: any) {
        return (<Text>{item['item']['data']['date']}</Text>)
    }
    
    function listEmpty(){
        return (<Text>Loading</Text>)
    }

    useEffect(() => {
        (async function () {
            await getRequests();
            setRefreshToggle(!refreshToggle)
        })()
    }, [])

    return (
        <SafeAreaView style = {styles.container}>
            <View style = {{flexDirection: 'row', justifyContent: 'center'}}>
                <TouchableOpacity style = { paymentsBtnActive ? styles.paymentsBtnActive : styles.paymentsBtnInactive } onPress = { () => { setRequestsBtnActive(paymentsBtnActive) 
                    setPaymentsBtnActive(!paymentsBtnActive) } } >
                    <Text style = { paymentsBtnActive ? styles.whiteText : styles.redText }>Payments</Text>
                </TouchableOpacity>
                <TouchableOpacity style = { requestsBtnActive ? styles.requestsBtnActive : styles.requestsBtnInactive } onPress = { () => { setPaymentsBtnActive(requestsBtnActive)
                    setRequestsBtnActive(!requestsBtnActive) } }  >
                    <Text style = { requestsBtnActive ? styles.whiteText : styles.redText }>Requests</Text>
                </TouchableOpacity>
            </View>


            <View style = {styles.summaryView}>
                <FlatList 
                    data={data} 
                    renderItem={renderItem} 
                    ListEmptyComponent = {listEmpty}
                    extraData = {refreshToggle}
                />
            </View>
        </SafeAreaView>
    );
    

You should have this instead你应该有这个

let [data, setData] = useState<any[]>([]);

const getRequests = useCallback(async function() {
   const body = {'phone': GLOBAL.userInfo['phone']}
   
   const options = {
      method: 'POST',
      headers: { 'Content-Type': 'application/json'},
      body: JSON.stringify(body)
   }

   let requests =  await fetch('http://3ef68e9c1352.ngrok.io/requests/user', 
   options);

   let requestsJSON = await requests.json();

   return requestsJSON['data']
}, []);

useEffect(() => {
  (async function () {
     const data = await getRequests();
     setData(data)
   })()
}, [])


<FlatList 
   data={data}
   renderItem={renderItem}
   ListEmptyComponent = {listEmpty}
/>

I ended up doing this:我最终这样做了:

export default function transactions({ navigation }: { navigation: any }) {
    const [paymentsBtnActive, setPaymentsBtnActive] = React.useState<boolean>(navigation.getParam('Pressed') == 'Payments');
    const [requestsBtnActive, setRequestsBtnActive] = React.useState<boolean>(navigation.getParam('Pressed') == 'Requests');
    const [data, setData] = React.useState<Array<any>>([]);

    async function getRequests() {
        const body = { 
            'phone': GLOBAL.userInfo['phone']
        }
        const options = {
            method: 'POST',
            headers: { 'Content-Type': 'application/json'},
            body: JSON.stringify(body)
        }
        let requests =  await fetch('http://3ef68e9c1976.ngrok.io/requests/user', options);
        let requestsJSON = await requests.json();
        setData(JSON.parse(JSON.stringify(requestsJSON['data'])))
    }    

    function renderItem(item: any) {
        console.log(item)
        return (<Text>{item['item']['data']['date']}</Text>)
    }
    
    function listEmpty(){
        return (<Text>Loading</Text>)
    }

    useEffect(() => {
        (async function () {
            await getRequests();
        })()
    }, [])

    return (
        <SafeAreaView style = {styles.container}>
            <View style = {{flexDirection: 'row', justifyContent: 'center'}}>
                <TouchableOpacity style = { paymentsBtnActive ? styles.paymentsBtnActive : styles.paymentsBtnInactive } onPress = { () => { setRequestsBtnActive(paymentsBtnActive) 
                    setPaymentsBtnActive(!paymentsBtnActive) } } >
                    <Text style = { paymentsBtnActive ? styles.whiteText : styles.redText }>Payments</Text>
                </TouchableOpacity>
                <TouchableOpacity style = { requestsBtnActive ? styles.requestsBtnActive : styles.requestsBtnInactive } onPress = { () => { setPaymentsBtnActive(requestsBtnActive)
                    setRequestsBtnActive(!requestsBtnActive) } }  >
                    <Text style = { requestsBtnActive ? styles.whiteText : styles.redText }>Requests</Text>
                </TouchableOpacity>
            </View>


            <View style = {styles.summaryView}>
                <FlatList 
                    data={data} 
                    renderItem={renderItem} 
                    ListEmptyComponent = {listEmpty}
                />
            </View>
        </SafeAreaView>
    );

This way when getRequests is called a new array with a difference reference is assigned to data so the Flatlist is re-rendered.这样,当调用getRequests时,会将具有差异引用的新数组分配给data ,以便重新渲染 Flatlist。

Because the all of the data was changing, this was not a scenario in which using extraData was necessary, nor the kind of scenario for which extraData was designed.因为所有的数据都在变化,所以这不是需要使用extraData的场景,也不是设计extraData的场景。 Nonetheless, my initial approach was inspired by this , and I am still not sure why it didn't work.尽管如此,我最初的方法是受此启发,但我仍然不确定为什么它不起作用。

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

相关问题 即使使用extraData = {this.state},PureComponent FlatList也不会重新呈现 - PureComponent FlatList not re-rendering even when using extraData={this.state} 功能组件中的 extraData flatlist 道具? - extraData flatlist prop in functional component? 为什么我的功能组件没有重新渲染? - Why is my functional component not re-rendering? 如何防止在 React 中的功能组件中重新渲染 - How to prevent re-rendering in functional component in React 在 React 功能组件中重新渲染 - 为什么会出现这种行为? - Re-rendering in React functional component - why this behavior? 当 redux state 更改时,功能组件不会重新渲染 - functional component is not re-rendering when redux state changes React.map 不在 state 上重新渲染功能组件的变化 - React .map not re-rendering on state change in functional component 在 Framer Preview 中更新时不会重新渲染功能组件数据 - Functional Component data not re-rendering on update in Framer Preview 在 React 中 state 更改后功能组件未重新渲染 - functional component is not re-rendering after state change in React 在 useCallback 挂钩中使用 Axios 时反应功能组件无限重新渲染? - React functional component re-rendering infinitely when using Axios in useCallback hook?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM