Home > database >  Objects are not valid as a React child (found: object with keys { my keys })
Objects are not valid as a React child (found: object with keys { my keys })

Time:01-27

when I submit my form with the const onSubmit, I fetch data. If the submit form is ok, I want to extract the data I get from my api. So I use, setState reponse : my data, and then I want to pass this data (reponse) to the component SingleLayout.

But it doesn't work. I get this error : [Error: Objects are not valid as a React child (found: object with keys {ID, Post Title, post_date, Prix, Surface, Ville, Category, featured_image, mandats_signes, date_de_signature_du_compromis}). If you meant to render a collection of children, use an array instead.]

Here the code :

export default class QueryChild extends Component {

  state = {
    username: "",
    password: "",
    isLogged: null,
    email: "",
    reponse: '',
    id: 4577
  }

  constructor(props) {
    super(props);
    this.render();


  }


  onSubmit = async() => { 
    const fetchValue = 'myAPI/suivi-dossier?'   'username='   this.state.username   '&password='   this.state.password   '&id='   this.state.id
    try {

        await fetch(fetchValue, {
            method: 'GET'
            
          })
          .then((response) => response.json())
          .then((responseJson) => {
              if(responseJson.success === true) {
                // I want to extract this : 
                this.setState({ reponse: responseJson.message })

                this.setState({ isLogged: true })


              } else {
                this.setState({reponse : responseJson.message });
                console.log(this.state.reponse)
              }
            
            // this.setState({
            //    data: responseJson
            // })
          })
          .catch((error) => {
            console.error(error);
          });

    } catch (err) {
        console.log(err)
    }

  }


    render() {

      if(this.state.isLogged === true) {
        // when user is Logged, I want to pass this.state.reponse to my component SingleLayout
        // but I get the error : [Error: Objects are not valid as a React child 
        // (found: object with keys {ID, Post Title, post_date, Prix, Surface, Ville, 
        // Category, featured_image, mandats_signes, date_de_signature_du_compromis}). If you 
        // meant to render a collection of children, use an array instead.]

        const SingleComponent = this.state.reponse.map(message => <SingleLayout key={message.ID} table={message}/> )
        

      
      return (
    <SafeAreaView>
          {SingleComponent}
    </SafeAreaView>
      );
      } else {
        return (
          <View style={styles.container}>
            <ScrollView>
                <ImageBackground source={image} resizeMode="cover" style={styles.image}>
                        <Spacer taille={70} />
                        <View style={styles.content}>
                            <Image
                            style={styles.imgLogo}
                            source={require('../../logo.png')}
                            />
                           
                            <Text style={styles.logo}>Pour des raisons de sécurité, veuillez entrer vos Identifiants</Text>
                            <View style={styles.inputContainer}>

                                <Text style={styles.textBasique}>{this.state.reponse}</Text>

                                <TextInput 
                                placeholder='Identifiant ou adresse email'
                                style={styles.input}
                                value={this.state.username}
                                onChangeText={val => this.setState({ username: val})}
                                />

                                <TextInput 
                                placeholder='Mot de passe'
                                style={styles.input}
                                value={this.state.password}
                                secureTextEntry= {true}
                                onChangeText={val => this.setState({ password: val})}
                                />


                                <Spacer taille={10} />
                                <Button title='Se Connecter' onPress={this.onSubmit}/>
                                <Spacer taille={10} />

                            </View>
                        </View>
                        <Spacer taille={200} />
                    </ImageBackground>
                </ScrollView>
        </View>
        )
      }
      }
    
      
}

Thank you.

CodePudding user response:

The response that comes from the server is an object. Since the "map" function only works with an array so, if you want to run this code you've to wrap "responseJson.message" into the array.

if(responseJson.success === true) {
     this.setState({ reponse: [responseJson.message] }) 
     this.setState({ isLogged: true })  
}

CodePudding user response:

It is because you can't map object like arrays. To get what you want, try below code

const SingleComponent = Object.keys(this.state.reponse).map(key => <SingleLayout key={key} table={this.state.reponse[key]}/> )

Here Object.keys(this.state.reponse) will give an array with keys of response object as values and by mapping that keys array , we can achieve the value of corresponding by this.state.reponse[key]

CodePudding user response:

Yes I get similar error after applying the solution because I found that the error comes from the setState reponse. So I added JSON.stringify and now the error is gone.

The code of Single Layout :

const SingleLayout = (props) => {
    let id = props.id
    let table = props.table
    
    console.log(table)

    const { colors } = useTheme();


        return (
            <View style={[styles.container, {backgroundColor: colors.background}]}>
                <Text>Bravo</Text>
            </View>
        )
}

Now with the solution : const SingleComponent = Object.keys(this.state.reponse).map(key => )

it works but it send caracters one by one

CodePudding user response:

SO I finally solved my problem :

the code i change :

QueryChild.tsx :

  if(responseJson.success === true) {
    //here : 
    this.setState({ reponse: JSON.stringify(responseJson.message) }) 

    this.setState({ isLogged: true })

and I directly return SingleLayout like that :

  return (
      <SafeAreaView>
          <SingleLayout table={this.state.reponse} />  
      </SafeAreaView>

Now I can access this.state.reponse into my SingleLayout :

const SingleLayout = (props) => {
    let id = props.id
    let table = props.table

    const myObj = JSON.parse(table);
    
    console.log(myObj[0].mandats_signes)
    console.log(myObj[0].ID)
    console.log(myObj[0].Category)
    //etc...

    const { colors } = useTheme();


        return (
            <View style={[styles.container, {backgroundColor: colors.background}]}>
                <Text>Bravo</Text>
            </View>
        )
    
}

CodePudding user response:

it's not a good practice to pass JSON and then parse.

I solved it and here is the link with the same solution that I presented to you: https://codesandbox.io/s/peaceful-bouman-qyi5y?file=/src/App.js

  •  Tags:  
  • Related