React Native - Nothing was returned from render - javascript

My application is stored in /src/index.js but i also have a /App.js and a /index.js.
I don't know the difference between these and i think thats the reason im getting this error.
/index.js
import { AppRegistry } from 'react-native';
import App from './App';
AppRegistry.registerComponent('client', () => App);
/App.js
import App from './src/index';
export default App;
/src/index.js
import React from 'react';
import { AppRegistry } from 'react-native';
import { Provider, connect } from 'react-redux';
import { addNavigationHelpers } from 'react-navigation';
import Navigator from './routes/route';
import store from './store/configureStore';
const App = ({ dispatch, nav }) => {
<Navigator
navigation={addNavigationHelpers({
dispatch,
state: nav,
})}
/>
};
const mapStateToProps = state => ({
nav: state.nav,
});
const AppWithNavigation = connect(mapStateToProps)(App);
export default () => {
<Provider store={store}>
<AppWithNavigation />
</Provider>
}
I used create react native package to build this project and then tried to follow some guides to implement react navigation with redux.

Your default export is not returning anything :
export default () => {
<Provider store={store}>
<AppWithNavigation />
</Provider>
}
To return JSX with an arrow function you need to use () => ( <JSX /> ) or the equivalent with curly braces : () => { return ( <JSX /> ) } :
export default () => (
<Provider store={store}>
<AppWithNavigation />
</Provider>
)
or :
export default () => {
return (
<Provider store={store}>
<AppWithNavigation />
</Provider>
)
}

You forgot to return the components
const App = ({ dispatch, nav }) => {
return(
<Navigator
navigation={addNavigationHelpers({
dispatch,
state: nav,
})}
/>
)
};
export default () => {
return(
<Provider store={store}>
<AppWithNavigation />
</Provider>
)
}

I didn't mention this
import React from 'react';
and all other react-native components in my other files of screens.
Because I was calling my screen component from another file, from App.js file, so I also had to import react and react-native components in that file too.

Related

How to use a hook in React?

I have information in the state (true or false) that I want to display if is true this Navbar component, but when I use the hook, I get an error message:
hook error
My code:
import React from 'react';
import { BrowserRouter } from 'react-router-dom';
import { Provider } from 'react-redux';
import { ConnectedRouter } from 'connected-react-router';
import store, { history } from './reduxStore';
import AppRouterContainer from './pages/AppRouterContainer';
import Feedback from './pages/feedback/Feedback';
import Navbar from './components/Navbar/Navbar';
import { useTypedSelector } from '../src/hooks/useTypedSelector';
const isAuth = useTypedSelector((state) => state.auth.isAuth);
const App = () => (
<BrowserRouter>
<Provider store={store}>
<ConnectedRouter history={history}>
<AppRouterContainer />
{isAuth && (
<Navbar />
)}
<Feedback />
</ConnectedRouter>
</Provider>
</BrowserRouter>
);
export default App;
You need to create a wrapper component to have access to store in your context (I think your useTypedSelector() hook needs that access).
You can use hooks only inside a function, not just inside a module.
Check out this example:
import React from 'react';
import { Provider } from 'react-redux';
import { BrowserRouter } from 'react-router-dom';
import { ConnectedRouter } from 'connected-react-router';
import { useTypedSelector } from '../src/hooks/useTypedSelector';
import Navbar from './components/Navbar/Navbar';
import AppRouterContainer from './pages/AppRouterContainer';
import Feedback from './pages/feedback/Feedback';
import store, { history } from './reduxStore';
const NavbarWrapper = () => {
const isAuth = useTypedSelector((state) => state.auth.isAuth);
if (!isAuth) {
return null;
}
return <Navbar />;
};
const App = () => (
<BrowserRouter>
<Provider store={store}>
<ConnectedRouter history={history}>
<AppRouterContainer />
<NavbarWrapper />
<Feedback />
</ConnectedRouter>
</Provider>
</BrowserRouter>
);
export default App;
Also, I think you should move the NavbarWrapper component to a separate file.

React Native, Redux can't find context

I'm new to redux and trying to grasp the concept of it. I'm receiving the error when redux is looking for context value. I'm sure that I wrapped the whole application in the Provider but still don't understand why it still results in the following error:
Error: could not find react-redux context value; please ensure the component is wrapped in a Provider
This is my themeReducer.js file:
const initialState = {
theme: "dark",
}
const themeReducer = (state = initialState, action) => {
if (action.type === "changeTheme"){
if (state.theme === "dark"){
return {theme: "light"};
} else {
return {theme: "dark"}
}
}
return state
}
export default themeReducer
This is my index.js for the store:
import {createStore, combineReducers} from 'redux';
import themeReducer from './reducers/themeReducer'
const rootReducer = combineReducers({
theme: themeReducer
})
const store = createStore(rootReducer)
export default store
Lastly, this is where I wrapped the root component with the provider to access the state:
import "react-native-gesture-handler";
import React from "react";
import { ThemeProvider } from "styled-components";
import AppNavContainer from "./src/navigations/index";
import { Provider } from "react-redux";
import { useSelector } from "react-redux";
import store from "./src/store/index"
export default function App() {
const currentTheme = useSelector(state => state.theme)
return (
<Provider store={store}>
<ThemeProvider theme={{ mode: {currentTheme} }}>
<AppNavContainer />
</ThemeProvider>
</Provider>
);
}
I'm using the styled component to access the theme value to change the background colour of my custom components. How I understand redux is that if I wrap everything under the Provider, I can access that state anywhere underneath that Provider. Did I do something wrong? Any opinions are appreciated
return (
<Provider store={store}>
<ThemeProvider theme={{ mode: {currentTheme} }}>
<AppNavContainer />
</ThemeProvider>
</Provider>
);
The store (and thus useSelector) is only available to components that are farther down the component tree from the Provider. So in ThemeProvider, in AppNavContainer, and anything inside AppNavContainer. You cannot use useSelector in App, because there is no Provider farther up the tree from App.
You'll probably want to split this component into multiple components. For example:
export default function App() {
return (
<Provider store={store}>
<ThemeWrapper />
</Provider>
);
}
function ThemeWrapper () {
const currentTheme = useSelector(state => state.theme)
return (
<ThemeProvider theme={{ mode: {currentTheme} }}>
<AppNavContainer />
</ThemeProvider>
);
}

React rendering an unexpected element

EDIT: I imported something wrong :facepalm:
Let me first run down what code ive written to get this output then I will tell you the expected output and what im confused about
App.jsx
import React from "react";
import Home from "./components/pages/HomePage";
import store from "./ducks/store";
import { Provider } from "react-redux";
import { BrowserRouter, Route, Switch } from "react-router-dom";
const App = () => {
return (
<BrowserRouter>
<Provider store={store}>
<Switch>
<Route exact path="/" component={Home} />
</Switch>
</Provider>
</BrowserRouter>
);
};
export default App;
Home.jsx
import React, { useEffect } from "react";
import FlexBox from "../../shared/FlexBox";
import BlogPostList from "./SortSettings";
import { useSelector, useDispatch } from "react-redux";
import { fetchAllBlogs } from "../../../ducks/blogs";
import {
getBlogData,
getBlogPosts,
getBlogTags,
} from "../../../ducks/selectors";
import SpinLoader from "../../shared/SpinLoader";
const Home = () => {
const blogData = useSelector((state) => getBlogData(state));
const blogPosts = useSelector((state) => getBlogPosts(state));
const blogTags = useSelector((state) => getBlogTags(state));
const dispatch = useDispatch();
useEffect(() => {
dispatch(fetchAllBlogs());
}, [dispatch]);
// TODO: handle if blogData.requestError comes back as true
if (blogData.isLoading || !blogPosts || !blogTags) {
return (
<FlexBox
alignItems="center"
justifyItems="center"
width="100vw"
height="100vh"
>
<SpinLoader />
</FlexBox>
);
}
return (
<FlexBox height="100vh" width="100vw">
<BlogPostList blogPosts={blogPosts} />
</FlexBox>
);
};
export default Home;
BlogPostList.jsx
import React from "react";
import BlogPost from "./BlogPost";
import FlexBox from "../../shared/FlexBox";
const BlogPostList = ({ blogPosts }) => {
return (
<FlexBox flexDirection="column">
Why in the world is this rendering a SortSettings component AHHHHHH!
</FlexBox>
);
};
export default BlogPostList;
Now my question is this why is it that the Home component is rendering a component as showed here https://gyazo.com/8cac1b28bdf72de9010b0b16185943bb what I would expect the Home component to be rendering is a BlogPostList if anyone has an idea help would be appreciated ive been stuck on this for awhile now (im pretty new so this might just be a noob mistake so sorry if its something obvious)

cannot navigate between views in react native

index.js
import React, { Component } from 'react';
import { AppRegistry } from 'react-native';
import Login from './src/screens/Login';
import Secured from './src/screens/Secured';
import NewPass from './src/screens/NewPass';
import { Provider } from 'react-redux';
import store from './store'; //Import the store
class ReactNativeStormpath extends Component {
state = {
isLoggedIn: false
}
render() {
if (this.state.isLoggedIn)
return (
<Provider store={store}>
<Secured
onLogoutPress={() => this.setState({isLoggedIn: false})}
/>
</Provider>
)
else
return (
<Provider store={store}>
<Login
onLoginPress={() => this.props.navigation.navigate('NewPass')}
/>
</Provider>
)
}
}
AppRegistry.registerComponent('ReactNativeStormpath', () => ReactNativeStormpath);
I receive "undefined is not an object", or the button doesn´t do anything,
i've followed almost all post and couldn't find a way to navigate between views in react native, this can't be that difficult.

React setting up a one-off route

I have an application that uses the same layout for all routes... except one.
One route will be completely different than all others.
So the entire application will have a menu, body, footer, etc.
The one-off route will not have any of that and be a completely separate thing.
How should I set this kinda thing up in a react app? Everything I've ever seen/done always has one main wrapping element that has the routes rendered as children.
index.js
import React from 'react'
import ReactDOM from 'react-dom'
import { BrowserRouter } from 'react-router-dom'
import { Provider } from 'react-redux'
import configureStore from './store'
import App from './components/App'
// import registerServiceWorker from './registerServiceWorker'
import { unregister } from './registerServiceWorker'
const preloadedState = window.__PRELOADED_STATE__ ? window.__PRELOADED_STATE__ : {}
// console.log('window.__PRELOADED_STATE__', window.__PRELOADED_STATE__)
delete window.__PRELOADED_STATE__
const Store = configureStore(preloadedState)
const rootEl = document.getElementById('root')
ReactDOM.hydrate(
<Provider store={Store}>
<BrowserRouter>
<App />
</BrowserRouter>
</Provider>,
rootEl
)
if(module.hot){
module.hot.accept('./components/App', () => {
ReactDOM.hydrate(
<Provider store={Store}>
<BrowserRouter>
<App />
</BrowserRouter>
</Provider>,
rootEl
)
})
}
// registerServiceWorker()
unregister()
App.js
import React, { Component } from 'react'
import { withRouter } from 'react-router-dom'
import { connect } from 'react-redux'
// Components
import AppHelmet from './AppHelmet'
import Notices from './Notices'
import Header from './Header'
import Body from './Body'
import Footer from './Footer'
// Site state
import { getSiteInfo } from '../store/actions/siteInfo'
import { REACT_APP_SITE_KEY } from '../shared/vars'
// CSS
import '../css/general.css'
class App extends Component {
initialAction() {
this.props.getSiteInfo(REACT_APP_SITE_KEY)
}
componentWillMount() {
// On client and site info has not been fetched yet
if(this.props.siteInfo.site === undefined){
this.initialAction()
}
}
render() {
return (
<div>
<AppHelmet {...this.props} />
<Notices />
<div className="body">
<Header />
<Body />
</div>
<Footer />
</div>
)
}
}
const mapStateToProps = (state) => {
return {
siteInfo: state.siteInfo,
user: state.user
}
}
const mapDispatchToProps = (dispatch) => {
return {
getSiteInfo: (siteKey) => dispatch(getSiteInfo(siteKey))
}
}
export default withRouter(connect(mapStateToProps, mapDispatchToProps)(App))
Body.js
import React, { Component } from 'react'
import { Switch, Route } from 'react-router-dom'
import routes from '../shared/routes'
class Body extends Component {
render() {
return (
<Switch>
{routes.map((route, i) => <Route key={i} {...route} />)}
</Switch>
)
}
}
export default Body
So, as you can see the index.js entry point will render <App />. <App /> will render the main layout, including <Body />, which renders all routes and content.
Cool.
But seeing as I don't want this one-off to render the <App /> layout, I'm not sure how to set this up from index.js. I'm sure it's simple and I'm just not seeing the answer.
One way to achieve what you want is to listen to the router.
You can add the listener into the components you want to hide.
When the listener detects you're on a view where you do not want the components to show, simply don't render them for that view.

Categories