This is my first go at using MobX so this may be a simpler problem than I imagine, but I'm not getting any errors with the things I've tried; the store is simply undefined wherever I try to use it. I've tried both importing the store directly into components and passing props from the main file (also with , but I'm not sure if I used that right). I've experimented with several different .babelrc file settings as well, but that doesn't seem to be an issue.
Here is the UserStore:
import React from 'react';
import { observable } from 'mobx';
class UserStore {
#observable info = {
username: "bob",
password: "secret",
email: "bob#email.com"
}
}
const userStore = new UserStore()
export default userStore;
Here is a simplified App.js:
import React, { Component } from 'react';
import { StyleSheet, Text, View } from 'react-native';
import Profile from './app/Profile.js';
import { UserStore } from './app/UserStore.js';
export default class App extends Component {
constructor(){
super();
this.state = {
page: 'Profile',
}
}
changePage(){
switch (this.state.page) {
case "Profile":
return <Profile logout={this.logout.bind(this)} userStore={UserStore}/>;
}
}
render() {
return (
<View>
{this.changePage()}
</View>
);
}
}
And here is a simplified Profile.js:
import React, { Component } from 'react';
import { StyleSheet, Text, View, Button } from 'react-native';
import { observer } from 'mobx-react/native';
#observer
export default class Profile extends Component {
render() {
console.log(this.props.userStore);
return (
<View>
<Text>Profile Page</Text>
<Text>username: {props from store go here}</Text>
<Text>password: {props from store go here}</Text>
<Text>email: {props from store go here}</Text>
</View>
);
}
}
All I'm trying to do right now is get the pre-defined observable "info" object from the store to the Profile.js component and display that information. This is being way more difficult than it should be - any insight is greatly appreciated!
Since you declared export default userStore; in UserStore.js
Try changing the way you import in App.js by removing the {}:
import UserStore from './app/UserStore.js';
{} is needed only if you want to do a named import. Here is a good read if you want to know more.
Related
Having issues accessing this custom component from the Screen Page. I'm sure the fix is straightforward
Component:
import React from 'react';
import { Text, View, Button } from 'react-native';
class Ohno extends React.Component {
render(){
return(
<Text>Test</Text>
)
}
}
export default Ohno
Screen:
import{ React, Component} from 'react'
import { View, Text} from 'react-native'
// import { Videoz } from '../Components/Video';
import { Ohno } from '../Components/Test';
class App2 extends Component {
render()
{
return (
<View>
<Ohno />
</View>
);
}
}
export default App2;
Looks super simple but not sure what is going on.
Continuing the answer given by #Ugur Eren, there are 2 exports, Named export and Default export.
Named exports: You can have multiple named exports from one file, and the import must be like
// ex. importing a named export:
import { MyComponent } from "./MyComponent";
// ex. Import named component with a different name using "as"
import { MyComponent as MyNewComponent } from "./MyComponent"
// exports from ./MyComponent.js file
export const MyComponent = () => {}
Default exports: There can only be one default export from each file. You can name it anything while importing.
// import
import MyDefaultComponent from "./MyDefaultExport";
// export
const MyComponent = () => {}
export default MyComponent;
New to react/redux here.
Getting error: Could not find "store" in either the context or props of "Connect(Books)". Either wrap the root component in a , or explicitly pass "store" as a prop to "Connect(Books)".
I've attached snippet of my code.
To see everything else, please check out my snack.
Thanks in advance!
https://snack.expo.io/#ganiyat1/colorful-thrills
import React, { useState } from 'react';
import { StyleSheet, SafeAreaView, TouchableOpacity, Text } from 'react-native';
import MaterialTabs from 'react-native-material-tabs';
import CardFlip from 'react-native-card-flip';
import { Card } from 'react-native-paper';
import { NewReleases } from '../shared/Booklist';
import { connect } from 'react-redux';
const mapStateToProps = (state) => {
return {
Booklists: state.Booklists
};
};
.....
export default connect(mapStateToProps)(Books);
Your root-node of the app has to wrapped with Redux Provider like:
import { Provider } from 'react-redux';
import store from 'your/path/to/redux/store';
...
return (
<Provider store={store}>
<Navigator />
</Provider>
);
Then you'll have the right to map any state into your component via connect
I am a beginner with React Native. I would like to pass data between two components. I get the following error:
TypeError: undefined is not an object (evaluating 'params.title'
App.js
import React from 'react';
import TabBar from './components/TabBar';
export default function App() {
return (
<TabBar title="Hall Building"/>
);
}
TabBar.js
import React, { useState } from 'react';
import { Text } from 'react-native';
export default function TabBar({ params }){
const [tabContent] = useState([
{
title: params.title,
}
])
return(
<Text>
{ tabContent.title }
</Text>
);
}
export { TabBar };
There are a couple things you're doing wrong in your TabBar component.
In theTabBar you are destructuring the property params but your property is called title. You either have to remove the curly braces or rename it to title. If you rename params to title you can remove params. and simply leave title. If you chose to remove the curly braces you can leave it as it is.
Then you also try to access tabContent.title but tabContent is an array with objects. You either have to remove the square brackets and pass an object as argument to useState OR you can access the title by getting the first index like so tabContent[0].title.
Change your TabBar into this :
import React, { useState } from 'react';
import { Text } from 'react-native';
export default function TabBar({ title }){
const [tabContent] = useState(title)
return(
<Text>
{ tabContent }
</Text>
);
}
export { TabBar };
hope it helps.
I have been using React Native for a few years and have only recently needed to utilise Redux on a new, more complex project. I am currently in the process of following a number of tutorials trying to work my way through the basics.
I am currently stuck with the following error:
Invariant Vilation: Could not find "store" in either the context of props of "Connect(App)"
I have found a number of posts with information about this error but because of the low amount of knowledge I currently have, I am unsure as to how to correctly implement a fix.
This project was created with create-react-native-app and I am using the Expo app to test.
In my eyes this should work because the root element of App is a Provider element passing the store as a prop which seems to contradict what the error is saying.
configureStore.js
import { createStore, applyMiddleware } from 'redux';
import app from './reducers';
import thunk from 'redux-thunk';
export default function configureStore() {
return createStore(app, applyMiddleware(thunk));
}
App.js:
import React from 'react';
import { Text } from 'react-native';
import { Provider, connect } from 'react-redux';
import configureStore from './configureStore';
import fetchPeopleFromAPI from './actions';
const store = configureStore();
export class App extends React.Component {
componentDidMount() {
props.getPeople()
}
render() {
const { people, isFetching } = props.people;
return (
<Provider store={store}>
<Text>Hello</Text>
</Provider>
);
}
}
function mapStateToProps(state) {
return {
people: state.people
}
}
function mapDispatchToProps(dispatch) {
return {
getPeople: () => dispatch(fetchPeopleFromAPI())
}
}
export default connect(mapStateToProps, mapDispatchToProps)(App);
You are trying to access the store in the App component even before it has been passed. Therefore it is not able to find the store.
You need to make a separate component and connect that using react-redux such as
<Provider store={store}>
<ConnectedComponent />
</Provider>
...
class ConnectedComponent extends React.Component {
componentDidMount () {
this.props.getPeople()
}
render() {
return (
<View>
<Text> ... </Text>
</View>
)
}
}
function mapStateToProps(state) {
return {
people: state.people
}
}
function mapDispatchToProps(dispatch) {
return {
getPeople: () => dispatch(fetchPeopleFromAPI())
}
}
export default connect(mapStateToProps, mapDispatchToProps)(ConnectedComponent);
I'm using the new react-navigation library for a React Native application I'm building. I'm having an issue with passing down my ActionCreators from my Nav component down to its scenes.
I have an AppContainer that wraps the entire application.
import React, { Component } from 'react';
import { DrawerNavigator, addNavigationHelpers } from 'react-navigation';
import { connect } from 'react-redux';
import { bindActionCreators } from 'redux';
import { ActionCreators } from '../actions';
import DashboardContainer from './DashboardContainer';
import CustomersContainer from './CustomersContainer';
const ApplicationNavigation = DrawerNavigator({
Dashboard: { screen: DashboardContainer },
Customers: { screen: CustomersContainer },
});
class AppContainer extends Component {
render() {
return (
<ApplicationNavigation />
);
}
}
function mapDispatchToProps(dispatch) {
return bindActionCreators(ActionCreators, dispatch);
}
export default connect(() => { return {} }, mapDispatchToProps)(AppContainer);
Here is the CustomerContainer:
import React, {Component} from 'react';
import {View, Text, Button} from 'react-native';
export default class CustomerContainer extends Component {
btnPressed() {
this.props.listCustomers()
}
render () {
return (
<View style={{marginTop: 40}}><Text>Customer</Text>
<Button onPress={() => this.btnPressed()} title="Press Me!" />
</View>
);
}
}
Now I'm trying to call an action within my CustomerContainer this.props.listCustomers(). The problem is the ActionCreator props aren't being passed down to the screens. I've tried doing adding the screenProps prop to the ApplicationNavigation component:
But for some reason when I do this my app doesn't display any screens its just blank with no errors.
UPDATE
So I updated my CustomerContainer file:
import React, {Component} from 'react';
import {View, Text, Button} from 'react-native';
import { connect } from 'react-redux';
import { bindActionCreators } from 'redux';
import { ActionCreators } from '../actions';
class CustomerContainer extends Component {
btnPressed() {
console.log(this.props.listCompanyCustomers())
}
render () {
return (
<View style={{marginTop: 40}}><Text>Customer</Text>
<Button onPress={() => this.btnPressed()} title="Press Me!" />
</View>
);
}
}
function mapStateToProps(state) {
return {
companyCustomers: state.companyCustomers
};
}
function mapDispatchToProps(dispatch) {
return bindActionCreators(ActionCreators, dispatch);
}
export default connect(mapStateToProps, mapDispatchToProps)(CustomerContainer);
This now works; however this feels like the incorrect way to go about this.
What redux connect basically does is:
Wrap your component
Declare contextProps to get access to dispatch
pass the dispatch to your component props.
If you pass the connect mapDispatchToProps, then it creates the mapping of the methods to dispatch.
So if you connect you AppContainer, its children won't get these dispatch methods, unless AppContainer passes them to its children (but this what connect comes to prevent).
So to sum up, you should connect any component that needs to use dispatch, otherwise it won't get it.
If you don't want to copy paste the mapDispatchToProps, you can just delete it and use this.props.dispatch instead:
import { ActionCreators } from '../actions';
class CustomerContainer extends Component {
btnPressed() {
this.props.dispatch(ActionCreators.listCompanyCustomers());
}
render () {
return (
<View style={{marginTop: 40}}><Text>Customer</Text>
<Button onPress={() => this.btnPressed()} title="Press Me!" />
</View>
);
}
}