简体   繁体   中英

how to fix Objects are not valid as a React child object promise

I create an eLearning app using react and want to split routes to many users (pupils, teachers, and admins) so I use this method

NewRoute.js

const NewRoute = ({
    component: Component,
    type: type,
    ...rest
}) => (
    <Route
        {...rest}
        render={ async props => {
            console.log(await CT.checkType(type));
            return CT.checkType(type) === false ? (
                <Redirect to='/login' />
            ) : (
                <Component {...props} />
            )
        }
        }
    />
);

checkType.js

export default {
  checkType: async (type) => {
    try{
      const res = await axios.get('/api/check/');
      console.log('api response',res);
      return true
    } catch(err) {
      console.error(err.message);
      return false
    }
  }
}

Uncaught Error: Objects are not valid as a React child (found: [object Promise]). If you meant to render a collection of children, use an array instead.

Uncaught Error: Objects are not valid as a React child (found: [object Promise]). If you meant to render a collection of children, use an array instead

You are getting this error because you are passing an async function to render , wich is a Promise object. You need to pass a React component. This means that this check CT.checkType(type) === false cannot be an async call.

So what you are trying to do is not possible.

If you want to render a component based on a request where is what you need.

You need to state that checks the following:

  • Check if it's loading
  • Check if it's valid or not

So you first set that the route is loading (rendering some Loading component). When the promise is done, you set is loading to false and set if it's valid or not, wich will return Redirect or Component .

I have done a very simple gist for this situation, but the logic is kind of this:

const PrivateRoute = ({ component: Component, ...otherProps }) => {

    const { isAuthenticated, isLoading } = useContext(AuthContext)

    return (
        <Route
            {...otherProps}
            render={props => (
                !isLoading
                    ?
                    (
                        isAuthenticated
                            ?
                            <Component {...props} />
                            :
                            <Redirect to={otherProps.redirectTo ? otherProps.redirectTo : '/signin'} />
                    )
                    :
                    <Loading />
            )}
        />
    )

}

And inside the AuthContext it calls a method that set isAuthenticated and isLoading based on async requests.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM