Vue Native: 'Invariant Violation' - react-navigation

I'm trying to get up and rolling with Vue Native, and I'm running into the same error whenever I attempt to navigate beyond the initial screen
Warning: React.createElement: 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 ReactVueComponent.
in ReactVueComponent (at SceneView.js:17)
in SceneView (at CardStack.js:466)
in RCTView (at View.js:60)
in View (at createAnimatedComponent.js:154)
in AnimatedComponent (at Card.js:12)
When searching my dir for ReactVueComponent, it doesn't exist, nor does SceneView.js, nor does RCTCView, etc. My guess is that's because they are generated with the code compiles?
My router, index.vue is set up as follows
<template>
<root>
<app-navigation></app-navigation>
</root>
</template>
<script>
import React from "react";
import { StackNavigator, navigationService } from "vue-native-router";
import { Root } from "native-base";
import WelcomeScreen from "./screen/WelcomeScreen.vue";
import HomeScreen from "./screen/home.vue";
const AppNavigation = StackNavigator(
{
Welcome: { screen: WelcomeScreen },
Home: { screen: HomeScreen }
},
{
initialRouteName: "Welcome",
headerMode: "none"
}
);
export default {
components: { Root, AppNavigation }
};
</script>
My WelcomeScreen component(this loads correctly. The button, on push, throws the error)
<template>
<nb-content padder>
<nb-form>
<view :style="{marginTop:300}">
<nb-button block :on-press="login">
<nb-text>Login</nb-text>
</nb-button>
</view>
</nb-content>
</template>
<script>
import { Dimensions, Platform, AsyncStorage } from "react-native";
import { NavigationActions } from "vue-native-router";
export default {
props: {
navigation: {
type: Object
}
},
methods: {
login() {
this.navigation.navigate("Home");
}
}
};
</script>
The HomeScreen component, which fails to render:
<template>
<nb-container :style="{flex:1, backgroundColor: '#fff'}">
<nb-header>
<nb-body>
<nb-title>title</nb-title>
</nb-body>
</nb-header>
<nb-content>
<nb-list>
<li>thing 1</li>
<li>thing 2</li>
<li>thing 3</li>
</nb-list>
</nb-content>
</nb-container>
</template>
<script>
import React from "react";
import { Dimensions } from "react-native";
const SCREEN_WIDTH = Dimensions.get("window").width;
export default {
props: {
navigation: Object
}
};
</script>
Any tips on this would be much appreciated. Not much out there on Vue Native yet, and I've tried to follow the few examples I've seen to the best of my ability. Double and triple-checked my dependencies and they all seem to be in place.

Seems like you are using <li> tags which are not supported. If you check native base docs. The correct tag to be used within nb-list is nb-list-item. http://docs.nativebase.io/Components.html#list-def-headref

Related

Laravel/Inertia how to register globally the Link component

I'm pretty new to Inertia (I have enough experience with Laravel), so I'm writting a toy SPA application. I learn that I must use the <Link ...> component instead of <a ...> to get the SPA behaivour. Problem is that I have to import the Link component on every other component that'll use links.
So, if I have a Page, I should do something like this:
<template>
...
<Link href="/about" class="...">
About Page
</Link>
...
</template>
<script>
import { Head, Link } from "#inertiajs/inertia-vue3";
export default {
components: {
Head,
Link,
},
...
};
</script>
And this works, but I think it's quite unefficient, boresome and so to have to import the Head and Link components for every page, after all a Link is the most common element on a page other than plan text.
Here https://inertiajs.com/releases/inertia-vue3-0.5.0-2021-07-13 in the documentation says you can register Link and Head components globally, so my app.js code looks like:
require("./bootstrap");
import { createApp, h } from "vue";
import { createInertiaApp } from "#inertiajs/inertia-vue3";
import { InertiaProgress } from "#inertiajs/progress";
import { Head, Link } from "#inertiajs/inertia-vue3";
const appName =
window.document.getElementsByTagName("title")[0]?.innerText || "Laravel";
createInertiaApp({
title: (title) => `${title} - ${appName}`,
resolve: (name) => require(`./Pages/${name}.vue`),
setup({ el, app, props, plugin }) {
createApp({ render: () => h(app, props) })
.use(plugin)
.component("InertiaHead", Head)
.component("InertiaLink", Link)
.mixin({ methods: { route } })
.mount(el);
},
});
As the documentation says, but this does nothing. When I comment the import ... and components section on my page component. It doesn't throw an error, but it doesn't display anything, not even the text.
Any idea?
You have registered your components as "InertiaLink" and "InertiaHead". If you do this, you must also name them that way in the vue files.
app.js
vue file

Vuex: Mutation occurs but state does not change

I'm Using Nuxt + Vuetify for a eCommerce app.
There are two separate components - Header and Cart.
The Header component contains a button which on click will toggle the cart visibility.
<template>
<v-app-bar>
<v-btn #click="$store.commit('toggleCart')" icon>
<v-icon>mdi-cart</v-icon>
</v-btn>
</v-app-bar>
</template>
<script>
import { mapState, mapMutations } from "vuex";
export default {
name: "Header",
methods: {
...mapState(["cartOpen"])
}
};
</script>
In the Cart component, I'm using Vuetify's drawer component which will be hidden by default and shown on click of the button in header.
<template>
<v-navigation-drawer v-model="cartOpen" app clipped right>Products in Cart</v-navigation-drawer>
</template>
<script>
import { mapState } from "vuex";
export default {
name: "Cart",
methods: {
...mapState(["cartOpen"])
}
};
</script>
This is my store index.js file
export const state = () => ({
cartOpen: false
})
export const mutations = {
toggleCart(state, cartOpen) {
return cartOpen = !cartOpen;
}
}
Now when I click on the button, a mutation happens in the develoer tools but the state is always false. Any help is appreciated.
The better way is to modify your mutation like this:
export const mutations = {
toggleCart(state) {
state.cartOpen = !state.cartOpen;
}
}
You shouldn't return anything from mutation, just set new value to state property.
As alternative:
You call your mutation without payload. You should add payload to your commit method:
<v-btn #click="$store.commit('toggleCart', cartOpen)" icon>
But you should also add cartOpen to you data which is not so good.

React Redux can't display an array that is a property of an object. What am I doing wrong?

I'm trying to display an object that's passed as props. One of the object properties is an array. The array is seen in the Redux store, is seen on console.log, is seen in the React tools, but when I try to map over it and display it as a list I get TypeError: Cannot read property 'map' of undefined. What am I doing wrong?
I tried to pass the tickets array as a separate prop but I still get the same error. And all the other properties of this.props.event are accessible.
This is my rendering component:
render(){
return(
<div>
{console.log('New EventDetails props event ', this.props.event)}
{console.log('New EventDetails props tickets ', this.props.tickets)}
<h1>Event name: {this.props.event.name}</h1>
<i>{this.props.event.id}</i>
<p>Event description: {this.props.event.description}</p>
<ul><h3>Tickets</h3>
{this.props.event.tickets.map(ticket =>{
return <Link to={`${this.props.event.id}/tickets/${ticket.id}`}><li key={ticket.id}><p>Price: {ticket.price}</p>
<p>Description: {ticket.description}</p>
</li> </Link>
})}
</ul>
</div>
)
}
}
This is the reducer:
import {DISPLAY_EVENT} from '../actions/events'
const eventReducer = (state={}, action) => {
console.log("single event reducer test, actin.payload: ", action.payload) //shows correct payload
switch(action.type) {
case DISPLAY_EVENT:
return action.payload
default:
return state
}
}
I'm passing the props from another component:
import React from 'react'
import {connect} from 'react-redux'
import EventDetails from './EventDetails'
import {getEvent} from '../actions/events'
class EventDetailsContainer extends React.Component {
componentDidMount() {
console.log("Component Did Mount test");
console.log('EventDetailsContainer props:', this.props);
this.props.getEvent(Number(this.props.match.params.id))
}
render() {
return (
<div>
<EventDetails event={this.props.event} tickets={this.props.tickets}/>
</div>
)
}
}
const mapStateToProps = state => {
return {
event: state.event,
tickets:state.event.tickets
}
}
export default connect(mapStateToProps, {getEvent})(EventDetailsContainer)
This is what I get from the console.logs.
I expected that the event.tickets[] will be accessible just as the other properties but instead it gives this error.
you console.log this.props.tickets but then you map over this.props.event.tickets

Sample usage of gatsby-plugin-recaptcha

I have to use gatsby-plugin-recaptcha for forms in my project. I am not able to find any example of usage of this plugin. It will be big help if someone can share any information regarding this.
Thanks
Place this code in your component
and import <Helmet/> from react-helmet.
<React.Fragment>
<Helmet>
<script src={`https://www.google.com/recaptcha/api.js?r=${Math.random()}`} async defer>
</script>
</Helmet>
<form>
<div className="g-recaptcha" data-sitekey={REACAPTCHA_PUBLIC}>
</div>
</form>
</React.Fragment>
` --> npm install --save reaptcha
import React, { Component } from 'react';
import Reaptcha from 'reaptcha';
class MyForm extends Component {
constructor(props) {
super(props);
this.state = {
verified: false
};
}
const onVerify = (recaptchaResponse) => {
this.setState({
verified: true
});
};
render() {
return (
Submit
);
}
}
see the reference: https://github.com/sarneeh/reaptcha`

ComponentWillMount gets called twice and render gets called twice. Also, render is being called before reducers finish. React and Redux

This is my console:
action: {type: "##redux/PROBE_UNKNOWN_ACTION_u.0.n.a.j.f"}
action: {type: "##redux/INIT2.4.j.c.2.m"}
in component will mount
inside the hangout_list render method
in component will mount
inside the hangout_list render method
Uncaught TypeError: Cannot read property 'map' of undefined
at HangoutList.render (bundle.js:22963)
at finishClassComponent (bundle.js:11048)
at updateClassComponent (bundle.js:11016)
at beginWork (bundle.js:11641)
at performUnitOfWork (bundle.js:14473)
at workLoop (bundle.js:14502)
at HTMLUnknownElement.callCallback (bundle.js:2759)
at Object.invokeGuardedCallbackDev (bundle.js:2797)
at invokeGuardedCallback (bundle.js:2846)
at replayUnitOfWork (bundle.js:13977)
...
bundle.js:12302 The above error occurred in the <HangoutList> component:
in HangoutList (created by Connect(HangoutList))
in Connect(HangoutList) (created by App)
in div (created by App)
in App
in Provider
...
action: {type: "FETCH_HANGOUTS", payload: {…}}
inside fetch hangouts in the reducer
action: {type: "FETCH_HANGOUTS", payload: {…}}
inside fetch hangouts in the reducer
As you can see, some console.logs are called twice and we have an undefined error which suggests some state data hasn't been set.
I have a react-redux app on localhost:8080 that uses ReduxPromise and is making an api call to localhost:3000 which succeeds... there data returns. It just never sets in time before the component tries to render. What can I do?
My code:
my main index.js:
import React from 'react';
import ReactDOM from 'react-dom';
import { Provider } from 'react-redux';
import { createStore, applyMiddleware } from 'redux';
import ReduxPromise from 'redux-promise'
import App from './components/app';
import reducers from './reducers';
const createStoreWithMiddleware = applyMiddleware(ReduxPromise)(createStore);
ReactDOM.render(
<Provider store={createStoreWithMiddleware(reducers)}>
<App />
</Provider>
, document.querySelector('.container'));
My action:
import axios from 'axios'
export const ROOT_URL = 'http://localhost:3000';
export const FETCH_HANGOUTS = 'FETCH_HANGOUTS';
export function fetchHangouts() {
const path = 'api/v1/hangouts'
const url = `${ROOT_URL}/${path}`;
const request = axios.get(url);
return {
type: FETCH_HANGOUTS,
payload: request
};
}
my App component:
import React, { Component } from 'react';
import HangoutList from '../containers/hangout_list'
export default class App extends Component {
render() {
return (
<div>
<HangoutList />
</div>
);
}
}
HangoutList container:
import React, { Component } from 'react';
import { connect } from 'react-redux';
import { bindActionCreators } from 'redux';
import { fetchHangouts } from '../actions/index';
class HangoutList extends Component {
renderHangouts(hangoutData) {
const type = hangoutData.type;
const additional_info = hangoutData.additional_info;
const hangoutKey = hangoutData.id;
return (
<tr key={hangoutKey}>
<td> {type} </td>
<td> {additional_info} </td>
</tr>
)
}
componentWillMount() {
console.log("in component will mount");
this.props.fetchHangouts();
}
render() {
console.log("inside the hangout_list render method");
return (
<table className="table table-hover">
<thead>
<tr>
<th>Type</th>
<th>Details </th>
</tr>
</thead>
<tbody>
{this.props.hangouts.map(this.renderHangouts)}
</tbody>
</table>
)
}
}
function mapStateToProps({ hangouts }) { // es6 shorthand. It's the same as if state was the argument and { hangouts: state.hangouts } was in the return section.
return { hangouts };
}
function mapDispatchToProps(dispatch) {
return bindActionCreators({ fetchHangouts }, dispatch)
}
export default connect(mapStateToProps, mapDispatchToProps)(HangoutList);
And finally my reducer:
import { FETCH_HANGOUTS } from "../actions/index";
export default function(state = [], action) {
console.log("action:", action);
switch (action.type) {
case FETCH_HANGOUTS:
// return state.concat([ action.payload.data ]); // don't use push. concat creates a new array, while push mutates the old one. YOu want to create a new array, not mutate the old one.
console.log("inside fetch hangouts in the reducer")
return action.payload.data
}
return state;
}
Anyone see what the issue is? I basically don't know why certain console.logs are running twice and why my api call (called in ComponentWillMount) won't finish before the container renders. I thought ReduxPromise was middleware that was supposed to handle this problem?

Resources