Functions are not valid as a React child. This may happen if you return a Component instead of from render . how can fix that

I have written a Payment component.

import React, {useState, useEffect  } from 'react';
import ProgressBar from "./ProgressBar";
import axios from "axios";
import Spinner from "./Spinner";
import State from "./State/State";

const Payment = props => {
    const [loading, isLoading] = useState(true);
    const [error, isError] = useState(false);
    let errMessage = useState('');
    useEffect(() => {
        axios.get('https://jsonplaceholder.typicode.com/todoss/1')
            .then(response => {
                if (response.status === 200) {
                    isLoading(false);
                    console.log(response.data);
                } else {
                    throw new Error('Something went wrong');
                }
            }).catch((error) => {
            console.log(error.message);
            isError(true);

        }).finally(() => {
            isLoading(false);
        });
    }, []);

    let state = null;
    if (loading) {
        state = <Spinner/>
    }
    if (error && !loading) {
        state = <State isSuccess={false} stateText={errMessage}/>;
    } else if (!error && !loading) {
        state = 'Payment page';
    }
    return (
        <>
            <ProgressBar finalStep={false} activeIndex={0}/>
            <div>
                {state}
            </div>
        </>
    );
};


export default Payment;

This is my spinner component

import React from 'react';
import './Spinner.css';
const Spinner = props => {
    return (
        <div className="orbit-spinner">
            <div className="orbit"></div>
            <div className="orbit"></div>
            <div className="orbit"></div>
        </div>
    );
};

export default Spinner;

CSS

.orbit-spinner, .orbit-spinner * {
    box-sizing: border-box;
}

.orbit-spinner {
    height: 250px;
    width: 250px;
    border-radius: 50%;
    perspective: 800px;
}

.orbit-spinner .orbit {
    position: absolute;
    box-sizing: border-box;
    width: 100%;
    height: 100%;
    border-radius: 50%;
}

.orbit-spinner .orbit:nth-child(1) {
    left: 0%;
    top: 0%;
    animation: orbit-spinner-orbit-one-animation 1200ms linear infinite;
    border-bottom: 3px solid #ff1d5e;
}

.orbit-spinner .orbit:nth-child(2) {
    right: 0%;
    top: 0%;
    animation: orbit-spinner-orbit-two-animation 1200ms linear infinite;
    border-right: 3px solid #ff1d5e;
}

.orbit-spinner .orbit:nth-child(3) {
    right: 0%;
    bottom: 0%;
    animation: orbit-spinner-orbit-three-animation 1200ms linear infinite;
    border-top: 3px solid #ff1d5e;
}

@keyframes orbit-spinner-orbit-one-animation {
    0% {
        transform: rotateX(35deg) rotateY(-45deg) rotateZ(0deg);
    }
    100% {
        transform: rotateX(35deg) rotateY(-45deg) rotateZ(360deg);
    }
}

@keyframes orbit-spinner-orbit-two-animation {
    0% {
        transform: rotateX(50deg) rotateY(10deg) rotateZ(0deg);
    }
    100% {
        transform: rotateX(50deg) rotateY(10deg) rotateZ(360deg);
    }
}

@keyframes orbit-spinner-orbit-three-animation {
    0% {
        transform: rotateX(35deg) rotateY(55deg) rotateZ(0deg);
    }
    100% {
        transform: rotateX(35deg) rotateY(55deg) rotateZ(360deg);
    }
}

This is my state component

import React from 'react';
import StateText from "./StateText/StateText";
import successImgSource from '../images/clipart1795386.png'
import rejectImgSource from '../images/PinClipart.com_syringe-clipart_316209.png';

const State = props => {
    return (
        <>
            <StateText isSuccess={props.isSuccess} stateText={props.stateText}/>
            <div>
                {props.isSuccess ?
                    <img src={successImgSource} style={{width: '40px', height: '40px'}} alt="Success tick image"/> :
                    <img src={rejectImgSource} style={{width: '40px', height: '40px'}} alt="Reject cross logo"/>
                }
            </div>

        </>
    );
}
;

export default State;

This is my stateText component

import React from 'react';
import StateTextClasses from "./StateText.module.css";



const StateText = props => {
    const classes = [StateTextClasses.stateText];
    if (props.isSuccess) {
        classes.push(StateTextClasses.success);
    } else {
        classes.push(StateTextClasses.reject)
    }
    return (
        <h2 className={classes.join(' ')}>{props.stateText}</h2>
    );
};


export default StateText;

CSS

.stateText {
    line-height: 1.04;
    margin-bottom: 30px;
}

.success {
    color: lightgreen;
}

.reject {
    color: indianred;
}

This is my app.js

import logo from './logo.svg';
import './App.css';
import {
    BrowserRouter as Router,
    Switch,
    Route,
    Link
} from "react-router-dom";
import ProgressBar from "./ProgressBar";
import Payment from "./Payment";

function App() {
    return (
        <Router>
            <div className="App">
            
                <Payment />
            </div>
        </Router>
    );
}

export default App;

The warning I am getting is

Functions are not valid as a React child. This may happen if you return a Component instead of <Component /> from render. Or maybe you meant to call this function rather than return it.

when response was rejected

How can I fix that?

Answer

Because you’re instantiating errMessage incorrectly in Payment, your attempt to display it in StateText is throwing this error.

Change your errMessage declaration to resemble those of the other state variables above it, and the error should go away.

Leave a Reply

Your email address will not be published. Required fields are marked *