I'm having problem with my App component not being returned properly, apparently.
App.jsx:
import React, { useState, useEffect } from 'react';
import { Route, Switch } from 'react-router-dom';
import UsersList from './components/UsersList';
import AddUser from './components/AddUser';
import About from './components/About';
import axios from 'axios';
const App = () => {
9
10 const [users, setUsers] = useState([]);
11 const [isUsername, setUsername] = useState('');
12 const [isEmail, setEmail] = useState('');
13
14
15 const getUsers = () => {
16 axios.get(`${process.env.REACT_APP_USERS_SERVICE_URL}/users`).then((res) => {
17 setUsers(res.data.data.users); }).catch((err) => {console.log(err); });
18 }
19
20 const handleSubmit = e => {
21 e.preventDefault();
22 const data = {
23 username: isUsername,
24 email: isEmail
25 };
26
27 axios.post(`${process.env.REACT_APP_USERS_SERVICE_URL}/users`, data)
28 .then(res => {
29 console.log(res);
30 getUsers();
31 setEmail('');
32 setUsername('');
33 }).catch(err => {console.log(err)} );
34 };
35
36 const handleChange = e => {
37 if(e.target.name === 'email') {
38 setEmail(e.target.value);
39 } else {
40 setUsername(e.target.value);
41 }
! 42 };
43
44 useEffect(() => {
45 getUsers();
46 }, [])
return (
29 <section className='section'>
28 <div className='container'>
27 <div className='columns'>
! 26 <div className='column is-half'>
25 <br />
! 24 <Switch>
! 23 <Route exact path='/' render={() => (
! 22 <>
! 21 <h1 className='title is-1'>All Users</h1>
! 20 <hr /><br />
! 19 <AddUser
! 18 email={isEmail}
! 17 username={isUsername}
! 16 handleChange={handleChange}
! 15 handleSubmit={handleSubmit}
14 />
13 <hr /><br />
12 <UsersList users={users} />
11 </>
10 )} />
9 <Route exact path='/about' component={About} />
8 </Switch>
7 </div>
6 </div>
5 </div>
4 </section>
3 )
2 };
1
79 export default App;
index.js:
import ReactDOM from 'react-dom';
import reportWebVitals from './reportWebVitals';
import { BrowserRouter as Router } from 'react-router-dom';
import App from './App';
reportWebVitals();
ReactDOM.render((<Router><App /></Router>), document.getElementById('root'));
AddUser.jsx:
import React from 'react';
1
2
3 const AddUser = props => {
4 return (
5 <form onSubmit={e => props.handleSubmit(e) }>
6 <div className='field'>
7 <input
8 name='username'
9 className='input is-large'
10 type='text'
11 placeholder='Enter a username'
12 onChange={e => props.handleChange(e)}
13 value={props.username}
14 required
15 />
16 </div>
17 <div className='field'>
18 <input
19 name='email'
20 className='input is-large'
21 type='email'
22 placeholder='Enter email'
23 onChange={e => props.handleChange(e)}
24 value={props.email}
25 required
26 />
27 </div>
28 <input
29 type='submit'
30 className='button is-primary is-large is-fullwidth'
31 value='Submit'
32 />
33 </form>
34 )
35 };
36
37 export default AddUser;
About.jsx:
import React from 'react';
1
2 const About = () => (
3 <div>
4 <h1 className='title is-1'>About</h1>
5 <hr /><br />
6 <p>About Page</p>
7 </div>
8 );
9
10 export default About;
UsersList.jsx:
import React from 'react';
1
2
3 const UsersList = props => {
4
5 return (
6 <div>
7 {
8 props.users.map((user) => {
9 return (
10 <React.Fragment>
11 <h4
12 key={user.id}
13 className='box title is-4'
14 >{ user.username }</h4>
15 </React.Fragment>
16 )
17 })
18 }
19 </div>
20 )
21 };
22
23 export default UsersList;
Error output:
Error: Element type is invalid: expected a string (for built-in components) or a class/function (for composite components) but got: undefined. You likely forgot to export your component from the file it's defined in, or you might have mixed up default and named imports.
Check the render method of `App`.
I see nothing wrong with how I'm exporting the App component or anything wrong with the how I'm returning it. Syntantically it appears OK. I've tried to add <React.Fragment></React.Fragment>
in case the app isn't being returned properly because I've got few elements there that needs to be wrapped in the fragment. That made no difference.
Note please I've got no render method because all my components are function-based hence no render method.
Any suggestions ?
CodePudding user response:
I duplicated your code into a codesandbox and with version 6.0.2 of react-router-dom
installed I see the same exact error as you've specified above. When I specify the latest v5.3.0 version the app renders without issue.
The issue that RRDv6 no longer exports a Switch
component (replaced by a Routes
component), and this is the import your code was using and having an issue with.
Reverting back to RRDv5 (npm un -s react-router-dom; npm i -s [email protected]
) will fix the issue, or you can follow the Upgrading from v5 docs to swap in the correct components from react-router-dom
v6.