Реактивный L oop при рендеринге предметов FlatList - PullRequest
0 голосов
/ 18 января 2020

Я бы создал 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 выполнялась петельные. Почему?

По этой ссылке вы можете найти весь код, который я написал для этой страницы.

1 Ответ

1 голос
/ 18 января 2020

Я вижу, что вы помещаете эту часть в функцию рендеринга:

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, и, в свою очередь, вызовите setEncData, когда вызов API будет успешным. Это вводит изменение состояния, и React снова вызывает Item () для повторного рендеринга, а затем вводится al oop. Чтобы решить эту проблему, вы можете поместить 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, вероятно, является объектом и не пройдет мелкую проверку на равенство

...