无法在模式中重新渲染FlatList。

问题描述 投票:0回答:1

* 我的目标是在每次调用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,
  },


});
javascript react-native modal-dialog
1个回答
0
投票

问题是这样的。你已经采取了 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 之间切换。现在,它的工作!请检查...

© www.soinside.com 2019 - 2024. All rights reserved.