Error rendering Sectionlist React Native

Asked

Viewed 160 times

0

I am having the following error in React-Native when trying to mount the component being passed from one screen to another.

inserir a descrição da imagem aqui

Below is the code to better understand the procedure.

Code that searches the data after login

import React, { Component } from 'react'
import {
  StyleSheet,
  Text,
  View,
  ImageBackground,
  KeyboardAvoidingView,
  StatusBar,
  TouchableOpacity,
  Alert,
  Image,
  TextInput,
  AsyncStorage
} from 'react-native'
import { server, showError } from '../common'
import axios from 'axios'
let requestOptions = {
  headers: {
    'Content-Type': 'application/x-www-form-urlencoded'
  }
}
export default class Auth extends Component {

  state = {
    logado: false,
    usuario: '',
    senha: '',
    obras: []
  }

  findObras = async () => {
    try {
      const res = await axios({
        method: 'post',
        url: `${server}/obras`,
        data: {
          usuario: this.state.usuario,
        },
        headers: requestOptions
      });
      this.setState({ obras: JSON.stringify(res.data) })
      Alert.alert('Fazer Login', JSON.stringify(res.data))
    } catch (error) {
      showError(error)
    }
  }
  login = async () => {
    if (this.state.usuario === '') {
      Alert.alert('Fazer Login', "Para ter acesso ao sistema é preciso se logar")
    } else {
      try {
        const res = await axios({
          method: 'post',
          url: `${server}/login`,
          data: {
            email: this.state.usuario,
            senha: this.state.senha
          },
          headers: requestOptions
        });
        this.findObras()
        this.setState({ logado: true })
        this.props.navigation.navigate('Home', {
          usuario: this.state.usuario,
          logado: this.state.logado,
          obras: this.state.obras
        })
      } catch (error) {
        showError(error)
      }
    }
  }

  render() {
    const { navigate } = this.props.navigation;
    return (
      <KeyboardAvoidingView behavior="padding" style={styles.container}>
        <View style={styles.loginContainer}>
          <Image resizeMode="contain" style={styles.logo} source={require('../../assets/logo-ageplan.png')} />
        </View>
        <View style={styles.formContainer}>
          <View style={styles.containerForm}>
            <StatusBar barStyle="light-content" />
            <TextInput style={styles.input}
              autoCapitalize="none"
              onSubmitEditing={() => this.passwordInput.focus()}
              autoCorrect={false}
              keyboardType='email-address'
              returnKeyType="next"
              placeholder='Usuário'
              onChangeText={usuario => this.setState({ usuario })}
              placeholderTextColor='rgba(225,225,225,0.7)' />

            <TextInput style={styles.input}
              returnKeyType="go" ref={(input) => this.passwordInput = input}
              placeholder='Senha'
              onChangeText={senha => this.setState({ senha })}
              placeholderTextColor='rgba(225,225,225,0.7)'
              secureTextEntry />
            <TouchableOpacity style={styles.buttonContainer} onPress={this.login}>
              <Text style={styles.buttonText}>LOGIN</Text>
            </TouchableOpacity>

            <TouchableOpacity>
              <Text style={styles.buttonTextSenha}>Esqueceu a senha?</Text>
            </TouchableOpacity>
          </View>
        </View>
      </KeyboardAvoidingView>
    )
  }
}
// define your styles
const styles = StyleSheet.create({
  container: {
    flex: 1,
    backgroundColor: '#696969',
  },
  loginContainer: {
    alignItems: 'center',
    flexGrow: 1,
    justifyContent: 'center'
  },
  logo: {
    position: 'relative',
    width: 300,
    height: 100
  },
  title: {
    color: "#FFF",
    marginTop: 120,
    width: 180,
    textAlign: 'center',
    opacity: 10
  },
  containerForm: {
    padding: 20
  },
  input: {
    height: 40,
    backgroundColor: 'rgba(225,225,225,0.2)',
    marginBottom: 10,
    padding: 10,
    color: '#fff'
  },
  buttonContainer: {
    backgroundColor: '#2980b6',
    paddingVertical: 15
  },
  buttonText: {
    color: '#fff',
    textAlign: 'center',
    fontWeight: '700'
  },
  loginButton: {
    backgroundColor: '#2980b6',
    color: '#fff'
  },
  buttonTextSenha: {
    color: '#fff',
    textAlign: 'center',
    fontWeight: '700',
    marginTop: 20
  },

});

Code where error occurs

import React, { Component } from 'react'
import {
  StyleSheet,
  Text,
  View,
  ImageBackground,
  TouchableOpacity,
  Alert,
  AsyncStorage,
  AppRegistry,
  SectionList
} from 'react-native'
import { server, showError } from '../common'
import axios from 'axios'
let requestOptions = {
  headers: {
    'Content-Type': 'application/x-www-form-urlencoded'
  }
}


export default class Auth extends Component {

  state = {
    usuario: this.props.navigation.state.params.usuario,
    logado: this.props.navigation.state.params.logado,
    obras: this.props.navigation.state.params.obras
  }
  render() {
    Alert.alert('Bem Vindo', this.state.usuario)
    return (
      <View style={styles.container}>
        <SectionList
          sections={this.state.obras}
          renderItem={({ item }) => <Text style={styles.item}>{item}</Text>}
          renderSectionHeader={({ section }) => <Text style={styles.sectionHeader}>{section.title}</Text>}
          keyExtractor={(item, index) => index}
        />
      </View>
    );
  }
}

const styles = StyleSheet.create({
  container: {
    flex: 1,
    paddingTop: 22
  },
  sectionHeader: {
    paddingTop: 2,
    paddingLeft: 10,
    paddingRight: 10,
    paddingBottom: 2,
    fontSize: 14,
    fontWeight: 'bold',
    backgroundColor: 'rgba(247,247,247,1.0)',
  },
  item: {
    padding: 10,
    fontSize: 18,
    height: 44,
  },
})

// skip this line if using Create React Native App
AppRegistry.registerComponent('AwesomeProject', () => SectionListBasics);

2 answers

0

When you no longer render the component, it may still happen that this.setState() is called if you have done asynchronous business logic on your component and later updated the local state of the component.

You made an asynchronous request for an API, the request (Promise) has not yet been resolved, but you have disassembled the component. Then the request is resolved, and this.setState() is called to define the new state, but reaches an unassembled component.

0


Marcos, you are trying to set the state before the component is mounted. First start the state with the empty attributes. then create into setState. Type like this:

componentDidMout() {
 const { usuario, logado, obras } = this.props.navigation.state.params
 this.setState({ usuario, logado, obras });
};

I’m just not sure about fetching the parameters like this. I remember something like this.props.navigation.getParams('seu_parametro'). But try it like I told you above.

Browser other questions tagged

You are not signed in. Login or sign up in order to post.