[英]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.