反应本机|循环渲染FlatList的项目

时间:2020-01-18 16:04:50

标签: react-native expo react-native-flatlist

我将为此FlatList创建一个Item

function Item({ marca, targa, index, allData, jwt }) {

  const [modalVisible, setModalVisible] = useState(false);
  const [encData, setEncData] = useState('');

  console.log(jwt);
  console.log(allData);

  const content = {
    data: allData
  }

  fetch('https://example.com/api/encrypt', {
    method: 'POST',
    body: JSON.stringify(content),
    headers: {
      'Content-Type': 'application/json; charset=utf-8',
      'authorization': jwt
    }
  })
  .then(response => response.json())
  .then(res => setEncData(res.message))
  .catch(err => console.log(err));

  return (
    <React.Fragment>
      <Modal
        animationType='fade'
        transparent={false}
        visible={modalVisible}
        onRequestClose={() => {
          Alert.alert('Modal has been closed.');
        }}
      >
        <View style={{flex:1, justifyContent: 'center', alignItems: 'center' }}>
          <View style={styles.modalInsideView}>                  
            <View style={{bottom: 50}}>
              <Text style={[styles.buttonText, styles.medium]}>{marca}   <Text style={styles.buttonText}>-   {targa}</Text></Text>
            </View>

            <Text>{JSON.stringify(encData)}</Text>

            <View style={{alignItems: 'center', justifyContent: 'center'}}>
              <TouchableOpacity style={[styles.button, {backgroundColor: '#00b0ff'}]} onPress={ () => setModalVisible(!modalVisible) }>
                <Ionicons
                  name={'ios-close'}
                  size={40}
                  style={{ color: 'white' }}
                />
              </TouchableOpacity>
            </View>
          </View>
        </View>
      </Modal>
      <TouchableOpacity 
        style={[styles.infoVehicle, {marginTop: index === 1 ? 10 : 18}]}
        onPress={ () => setModalVisible(true) }>
        <View style={{flexDirection:'row', alignItems: 'stretch', alignItems: 'center', justifyContent: 'space-between'}}>
          <View style={{}}>
            <Text style={[styles.buttonText, styles.medium]}>{marca}   <Text style={styles.buttonText}>-   {targa}</Text></Text>
          </View>
          <View style={{}}>
            <Image
              style={{width: 40, height: 40, opacity: 0.5}}
              source={require('../../images/qr-example.png')}
            />
          </View>
        </View>
      </TouchableOpacity>
    </React.Fragment>
  );
}

但是,我意识到元素<Text>{JSON.stringify(encData)}</Text>的内容不断变化,就好像Item函数正在循环一样。为什么?

在此link上,您可以找到我为页面编写的所有代码。

1 个答案:

答案 0 :(得分:1)

我可以看到您正在将这部分放在render函数中

fetch('https://example.com/api/encrypt', {
    method: 'POST',
    body: JSON.stringify(content),
    headers: {
      'Content-Type': 'application/json; charset=utf-8',
      'authorization': jwt
    }
  })
  .then(response => response.json())
  .then(res => setEncData(res.message))
  .catch(err => console.log(err));

React可以调用函数Item()进行多次渲染,并且每次都会引入新的API调用,并且在api调用成功时依次调用setEncData。那会导致状态改变,React将再次调用Item()来重新渲染,然后引入一个循环。要解决此问题,您可以将fetch()放在useEffect内,如下所示:

useEffect(() => {
const content = {
    data: allData
  }
fetch('https://example.com/api/encrypt', {
    method: 'POST',
    body: JSON.stringify(content),
    headers: {
      'Content-Type': 'application/json; charset=utf-8',
      'authorization': jwt
    }
  })
  .then(response => response.json())
  .then(res => setEncData(res.message))
  .catch(err => console.log(err));
}, []) // make this an empty array

更新:allData可能是一个对象,不会通过浅等式检查