* 我的目标是在每次调用generateNewTicket()时能够重新渲染数据。然而,只有当我接触到票据时,才会重新渲染。.
我试着用tryOut[我肯定是在无知的情况下]来改变状态,但是没有成功。
如果我将modalVisible设置为false,然后立即将其设置为true,就能正常工作,但系统首先从modal中出来,然后我需要点击才能再次看到modal。
import React, { useState } from 'react';
import {
SafeAreaView,
View,
TouchableOpacity,
TouchableHighlight,
FlatList,
StyleSheet,
Text,
Modal,
Alert,
Button,
BackHandler,
} from 'react-native';
import Constants from 'expo-constants';
import Welcome from './Welcome';
const DATA = [
{
id: '11',
title: ' ',
},
{
id: '12',
title: ' ',
},
{
id: '13',
title: ' ',
},
{
id: '14',
title: ' ',
},
{
id: '15',
title: ' ',
},
{
id: '16',
title: ' ',
},
{
id: '21',
title: ' ',
},
{
id: '22',
title: ' ',
},
{
id: '23',
title: ' ',
},
{
id: '24',
title: ' ',
},
{
id: '25',
title: ' ',
},
{
id: '26',
title: ' ',
},
];
generateNewTicket();
Function generateNewTicket() {
for (i=0; i < 12; i++) {
DATA[i] = Math.floor(Math.random() * 1000)+1000}
}
function Item({ id, title, selected, onSelect }) {
return (
<TouchableOpacity
onPress={() => onSelect(id)}
style={[
styles.item,
{ backgroundColor: selected && title != ' ' ? 'yellow' : '#f9c2ff' },
]}
>
<Text style={styles.title}>{title}</Text>
</TouchableOpacity>
);
}
export default function App() {
const [selected, setSelected] = React.useState(new Map());
const onSelect = React.useCallback(
id => {
const newSelected = new Map(selected);
newSelected.set(id, !selected.get(id));
setSelected(newSelected);
},
[selected],
);
const [modalVisible, setModalVisible] = React.useState(true);
return (
<SafeAreaView style={styles.container}>
<Text style={styles.titleText}>
Test Program
</Text>
<Modal
animationType="slide"
transparent={false}
visible={modalVisible}
>
<FlatList
style={styles.ticketposition}
data={DATA}
numColumns={6}
renderItem={({ item }) => (
<Item
id={item.id}
title={item.title}
selected={!!selected.get(item.id)}
onSelect={onSelect}
/>
)}
keyExtractor={item => item.id}
extraData={tryOut }
/>
<TouchableHighlight
style={{ ...styles.openButton, backgroundColor: "#2196F3" }}
onPress={() => {
tryOut = tryOut++;
generateNewTicket();
}}
>
<Text style={styles.textStyle}>Exit Program</Text>
</TouchableHighlight>
</Modal>
<TouchableHighlight
style={styles.openButton}
onPress={() => {
setModalVisible(!modalVisible);
}}
>
<Button
style={styles.primaryButton}
title="Test Program"
color="lightcoral"
onPress={() => {
setModalVisible(!modalVisible);
}}
/>
</TouchableHighlight>
</SafeAreaView>
);
}
const styles = StyleSheet.create({
container: {
flex: 1,
marginTop: 100,
marginHorizontal: 15,
},
item: {
backgroundColor: '#f9c2ff',
padding: 0, //1
marginVertical: 8,
marginHorizontal: 1,
width: 36, //40
justifyContent: 'center',
alignItems: 'center',
},
title: {
fontSize: 32,
},
titleText: {
fontSize: 50,
fontWeight: "bold",
fontSize: 20,
marginHorizontal: 135,
marginBottom: 20,
},
textStyle: {
fontSize: 20,
marginHorizontal: 125,
},
primaryButton: {
fontSize: 30,
padding: 20,
marginTop: 10,
marginTop: 50,
color: '#c3c3c3',
marginBottom: 20,
width: 150,
},
ticketposition: {
marginTop: 50,
marginLeft: 20,
},
});
问题是这样的。你已经采取了 DATA
作为 const
. 你想改变它。这是一个问题。即使是你定义 DATA
作为 var
జజజజజజజజజజజజజజజజజజజజజజజజజజజజజజజజజజజజజజజ Flatlist
当你改变它时,不会重新渲染。因为 React Native
并不根据在此基础上所做的更改重新渲染任何组件。var
或任何其他类似的类型。但它会重新渲染特定的组件,如果一个 state
值被改变。
所以,你必须输入你的 data
作为 state
. 当你改变你的 data
,你必须改变和更新 state
. 当 state
值被改变,它将重新渲染 Flatlist
请看下面的代码...
import React, { useState } from 'react';
import {
SafeAreaView,
View,
TouchableOpacity,
TouchableHighlight,
FlatList,
StyleSheet,
Text,
Modal,
Alert,
Button,
BackHandler,
} from 'react-native';
import Constants from 'expo-constants';
const DATA = [
{
id: '11',
title: ' ',
},
{
id: '12',
title: ' ',
},
{
id: '13',
title: ' ',
},
{
id: '14',
title: ' ',
},
{
id: '15',
title: ' ',
},
{
id: '16',
title: ' ',
},
{
id: '21',
title: ' ',
},
{
id: '22',
title: ' ',
},
{
id: '23',
title: ' ',
},
{
id: '24',
title: ' ',
},
{
id: '25',
title: ' ',
},
{
id: '26',
title: ' ',
},
];
function Item({ id, title, selected, onSelect }) {
return (
<TouchableOpacity
onPress={() => onSelect(id)}
style={[
styles.item,
{ backgroundColor: selected && title != ' ' ? 'yellow' : '#f9c2ff' },
]}>
<Text style={styles.title}>{id}</Text>
</TouchableOpacity>
);
}
export default function App() {
const [selected, setSelected] = React.useState(new Map());
const [modalVisible, setModalVisible] = React.useState(false);
const [data, setData] = React.useState(DATA);
const [trigger, setTrigger] = React.useState(false);
const onSelect = React.useCallback(
(id) => {
const newSelected = new Map(selected);
newSelected.set(id, !selected.get(id));
setSelected(newSelected);
},
[selected]
);
const generateNewTicket = () => {
var newData = data;
var i;
for (i = 0; i < 12; i++) {
newData[i] = {
id: (Math.floor(Math.random() * 1000) + 1000).toString(),
title: ' ',
}
}
setData(newData);
setTrigger(!trigger)
};
return (
<SafeAreaView style={styles.container}>
<Text style={styles.titleText}>Test Program</Text>
<Modal animationType="slide" transparent={false} visible={modalVisible}>
<FlatList
style={styles.ticketposition}
data={data}
numColumns={6}
renderItem={({ item }) => (
<Item
id={item.id}
title={item.title}
selected={!!selected.get(item.id)}
onSelect={onSelect}
/>
)}
keyExtractor={(item) => item.id}
/>
<TouchableHighlight
style={{ ...styles.openButton, backgroundColor: '#2196F3', marginBottom: 20 }}
onPress={generateNewTicket}>
<Text style={styles.textStyle}>Try Out</Text>
</TouchableHighlight>
<TouchableHighlight
style={{ ...styles.openButton, backgroundColor: '#2196F3' }}
onPress={() => setModalVisible(!modalVisible)}>
<Text style={styles.textStyle}>Exit Program</Text>
</TouchableHighlight>
</Modal>
<TouchableHighlight
style={styles.openButton}
onPress={() => {
setModalVisible(!modalVisible);
}}>
<Button
style={styles.primaryButton}
title="Test Program"
color="lightcoral"
onPress={() => {
setModalVisible(!modalVisible);
}}
/>
</TouchableHighlight>
</SafeAreaView>
);
}
const styles = StyleSheet.create({
container: {
flex: 1,
marginTop: 100,
marginHorizontal: 15,
},
item: {
backgroundColor: '#f9c2ff',
padding: 0, //1
marginVertical: 8,
marginHorizontal: 1,
width: 36, //40
justifyContent: 'center',
alignItems: 'center',
},
title: {
fontSize: 32,
},
titleText: {
fontWeight: 'bold',
fontSize: 20,
marginHorizontal: 135,
marginBottom: 20,
},
textStyle: {
fontSize: 20,
marginHorizontal: 125,
},
primaryButton: {
fontSize: 30,
padding: 20,
marginTop: 50,
color: '#c3c3c3',
marginBottom: 20,
width: 150,
},
ticketposition: {
marginTop: 50,
marginLeft: 20,
},
});
这里,我已经通过了 data
作为 state
. 当你打电话 generateNewTicket()
,它改变了 state
价值 data
. 即使你改变了 data
在这里,它不会重新渲染,因为它不承认有差异。有时会出现这种情况。所以,我做的是,用另一个 state
叫做 trigger
之间切换。现在,它的工作!请检查...