How to debug a ExecJS error in react-rails - ruby-on-rails-5

I am getting;
Encountered error "#<ExecJS::ProgramError: 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.>
I only get it, once I switch to prerender:true, before that I was not getting any import related errors.
How could I debug this? What might be the cause of the problem?
The component throwing the error looks like:
import React from "react";
import { configureStore } from "#reduxjs/toolkit";
import { Provider } from 'react-redux'
import {
myReducer,
} from "./redux/reducers/reducers";
import Main from "./Main";
const store = configureStore({
reducer: {
myReducer: myReducer,
},
});
function App(props) {
return (
<Provider store={store}>
<Main current_user={props.current_user}></Main>
</Provider>
);
}
export default App;

Related

React native MobX store - MobX injector: Store is not available

I'm using the following template: https://github.com/cawfree/create-react-native-dapp
I have used the provider component in the top level (parent) component like so:
import { Provider } from 'mobx-react';
import SettingsStore from '../../store/settings';
return (
<Provider store={SettingsStore}>
<View style={[StyleSheet.absoluteFill, styles.center, styles.white, !loading && {justifyContent: 'space-between'}]}>
{loading ?
<FadeOutImage />
:
<Welcome />
}
</View>
</Provider>
);
Here's my SettingsStore in file settings.js:
import {makeAutoObservable} from 'mobx';
class SettingsStore {
darkMode = false
constructor() {
makeAutoObservable(this)
}
toggleDarkMode = () => {
this.darkMode = !this.darkMode
}
}
export default new SettingsStore();
The following is where I am injecting the store. It's the child component <Welcome />:
import { inject, observer } from "mobx-react";
const Welcome () => {
return (<View><Text>test</Text></View>)
}
export default inject("SettingsStore")(observer(Welcome));
I have checked that the paths for the imports is correct (would get another error otherwise). I just cannot understand why I am seeing the following err:
What's going wrong and how can I fix this?
You passing in under the name store into Provider (<Provider store={SettingsStore}>), so when injecting you need to use same prop name inject("store"). Or change prop name to SettingsStore: <Provider SettingsStore={SettingsStore}>

Can I store a component in the redux?

I want to only once import the component 'MessageDialog' in the index.js and use it in other pages. So I store the component in the redux. But I get an error when entering the page.
I haven't done this. Can I store a component in the redux?
index.js:
import { MessageDialog } from 'miot/ui';
...
let data = {
MessageDialog: <MessageDialog />,
messageDialogOptions: {
title: '我是标题',
message: '我是内容',
cancel: '取消',
confirm: '确认',
cancelable: false,
visible: true
}
};
let store = createStore(reducers, data);
export default class App extends React.Component {
render() {
return (
<Provider store={store}>
<RootStack />
</Provider>
);
}
}
Invariant Violation:
Element type is invalid: expected a string (for built-in components) or a class/function (for composite components) but got: object.
I hope to successfully render the page.
Redux is not meant to store components. You should only store props for your components.
Make your component react to datas you are storing in redux instead of trying to store component itself.

Getting undefined is not an object (evaluating 'props.navigation.addListener')

I am trying to implement HOC for Backhandler. I have 3 component all are wrapped in createBottomTabNavigator, home is one of them. but before implementing backhandling ,HOC showing this error.
Component home-
import React, { Component } from 'react';
import {Text,View} from 'react-native';
import updateComponent from './HOC/updateComponent';
class home extends Component {
constructor(props) {
super(props);
}
render() {
return (
<View><Text> HOC</Text></View>
);
}
}
export default updateComponent(home);
HOC updateComponent
import React, { Component } from 'react';
const updateComponent = WrappedComponent => {
class NewComponent extends Component {
constructor(props) {
super(props);
}
render() {
return <WrappedComponent />;
}
}
return NewComponent;
};
export default updateComponent;
Your home component should be capitalized, from React docs:
When an element type starts with a lowercase letter, it refers to a
built-in component like or and results in a string 'div'
or 'span' passed to React.createElement. Types that start with a
capital letter like compile to React.createElement(Foo) and
correspond to a component defined or imported in your JavaScript file.
We recommend naming components with a capital letter. If you do have a
component that starts with a lowercase letter, assign it to a
capitalized variable before using it in JSX.
Another thing (not sure causing the error but you'll have bugs later on), is that you don't pass the props to the NewComponent, which means every time you will wrap a component with updateComponent you'll lose all the props.
Solution:
home -> Home.
return <WrappedComponent /> --> return <WrappedComponent {...this.props} />.

Invariant Violation in React-Native

I am new to React Native.
When I go to run project on Android emulator this error displayed.
I tried many solutions but didn't work.
Error log:
Invariant Violation: Element type is invalid:
expected a string (for built-in components) or a class/function
(for composite components) but got: undefined.
LoginForm.js codes:
import React, {Component} from 'react';
import {View} from 'react-native';
import {Button,Card,CardSection} from './components'
class LoginForm extends Component{
render(){
return(
<Card>
<CardSection>
<Button>
Log in
</Button>
</CardSection>
</Card>
);
}
}
export default LoginForm;
App.js codes:
import React,{Component} from 'react';
import {View} from 'react-native';
import {Header} from './components';
import LoginForm from './components';
class App extends Component{
render(){
return(
<View>
<Header headertext="Test"/>
<LoginForm />
</View>
);
}
}
export default App;
index.js
import { AppRegistry } from 'react-native';
import App from './src/App';
AppRegistry.registerComponent('second', () => App);
components/index.js
export * from './Button';
export * from './Card';
export * from './CardSection';
export * from './Header';
In your components/index.js, you are exporting everything except LoginForm.js
So, when you're importing LoginForm from "./components" in App.js, it looks in the index.js file and doesn't find a default export.
You can add export * from "./LoginForm" in your components/index.js and import it as a named import in App.js, such as: import {LoginForm} from "./components".
Or maybe you could import LoginForm from "./components/LoginForm" directly.

react-router 4 - Browser history needs a DOM

I am trying server side rendering using react-router 4. I am following the example provided here https://reacttraining.com/react-router/web/guides/server-rendering/putting-it-all-together
As per the example on server we should use StaticRouter. When I import as per the example I am seeing StaticRouter as undefined
import {StaticRouter} from 'react-router';
After doing some research online I found I could use react-router-dom. Now my import statement looks like this.
import {StaticRouter} from 'react-router-dom';
However when I run the code I am getting Invariant Violation: Browser history needs a DOM in the browser.
my server.js file code
....
app.get( '*', ( req, res ) => {
const html = fs.readFileSync(path.resolve(__dirname, '../index.html')).toString();
const context = {};
const markup = ReactDOMServer.renderToString(
<StaticRouter location={req.url} context={context} >
<App/>
</StaticRouter>
);
if (context.url) {
res.writeHead(302, {
Location: context.url
})
res.end();
} else {
res.send(html.replace('$react', markup));
}
} );
....
And my client/index.js code
....
ReactDOM.render((
<BrowserRouter>
<App />
</BrowserRouter>
), root);
....
Update v1
Reduced my example to a bear minimum and still getting the same error.
clientIndex.js
import ReactDOM from 'react-dom'
import { BrowserRouter } from 'react-router-dom'
import App from '../App'
ReactDOM.render((
<BrowserRouter>
<App/>
</BrowserRouter>
), document.getElementById('app'))
serverIndex.js
import { createServer } from 'http'
import React from 'react'
import ReactDOMServer from 'react-dom/server'
import { StaticRouter } from 'react-router'
import App from '../App'
createServer((req, res) => {
const context = {}
const html = ReactDOMServer.renderToString(
<StaticRouter
location={req.url}
context={context}
>
<App/>
</StaticRouter>
)
res.write(`
<!doctype html>
<div id="app">${html}</div>
`)
res.end()
}).listen(3000);
App.js
import React from 'react';
import { BrowserRouter as Router, Route } from 'react-router-dom';
import routes from "./client/routes";
const App = ( ) => (
<Router>
<Route path="/" exact render={( props ) => ( <div>Helloworld</div> )} />
</Router>
)
export default App;
You need to use different history provider for server side rendering because you don't have a real DOM (and browser's history) on server. So replacing BrowserRouter with Router and an alternate history provider in your app.js can resolve the issue. Also you don't have to use two wrappers. You are using BrowserRouter twice, in app.js as well as clientIndex.js which is unnecessary.
import { Route, Router } from 'react-router-dom';
import { createMemoryHistory } from 'history';
const history = createMemoryHistory();
<Router history={history}>
<Route path="/" exact render={( props ) => ( <div>Helloworld</div> )} />
</Router>
You can now replace StaticRouter with ConnectedRouter which can be used both in client and server. I use the following code to choose between history and export it to be used in ConnectedRouter's history.
export default (url = '/') => {
// Create a history depending on the environment
const history = isServer
? createMemoryHistory({
initialEntries: [url]
})
: createBrowserHistory();
}
In clientIndex.js
Rather than BrowserRouter use StaticRouter.
import { BrowserRouter } from 'react-router-dom';
import { StaticRouter } from 'react-router-dom'
As is essentially noted in the comments, one may hit this error (as I have) by accidentally wrapping your App component in a <BrowserRouter>, when instead it is your client app that should be wrapped.
App.js
import React from 'react'
const App = () => <h1>Hello, World.</h1>
export default App
ClientApp.js
import React from 'react'
import { BrowserRouter } from 'react-router-dom'
import ReactDOM from 'react-dom'
import App from './App'
const render = Component => {
ReactDOM.render(
<BrowserRouter>
<Component />
</BrowserRouter>,
document.getElementById('app')
)
}
render(App)
See also the React Router docs.