In my project I faced the above error can anyone tell me how to solve this error.
The error I faced is:
Error: useTheme must be used within NativeBaseConfigProvider
This error is located at:
in Container
in ProductContainer (created by App)
in RCTView (created by View)
in View (created by App)
in App (created by ExpoRoot)
in ExpoRoot
in RCTView (created by View)
in View (created by AppContainer)
in RCTView (created by View)
in View (created by AppContainer)
in AppContainer
ProductContainer.js:
import React, { useState, useEffect } from 'react'
import { View, StyleSheet, ActivityIndicator, FlatList, Text} from 'react-native'
import { Container, Header, Icon, Item, Input } from 'native-base';
import ProductList from './ProductList';
import SearchedProduct from './SearchedProducts';
const data = require('../../assets/data/products.json');
const ProductContainer = () => {
const [products, setProducts ] = useState([]);
const [productsFiltered, setProductsFiltered] = useState([]);
const [focus, setFocus] = useState();
useEffect(() => {
setProducts(data);
setProductsFiltered(data);
setFocus(false);
return () => {
setProducts([])
setProductsFiltered([])
setFocus()
}
}, [])
const SearchProduct = (text) => {
setProductsFiltered(
products.filter((i) => i.name.toLowerCase().includes(text.toLowerCase()))
);
}
const openList = () => {
setFocus(true);
}
const onBlur = () => {
setFocus(flase);
}
return (
<Container>
<View style = {{ flexDirection: "row"}}>
<Input
width = "100%"
variant = "rounded"
placeholder="Search"
onFocus={openList}
onChangeText={(text) => SearchProduct(text)}
/>
</View>
{focus == true ? (
<SearchProduct
productsFiltered={productsFiltered}
/>
) : (
<View style={styles.container}>
<Text>Product Container</Text>
<View style={styles.listContainer}>
<FlatList
data={products}
numColumns={2}
renderItem={({item}) => <ProductList
key={item.brand}
item={item}/>}
keyExtractor={item => item.brand}
/>
</View>
</View>
)}
</Container>
)
}
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: '#fff',
alignItems: 'center',
justifyContent: 'center',
},
});
export default ProductContainer
App.js
import { StatusBar } from 'expo-status-bar';
import React from 'react';
import { StyleSheet, Text, View } from 'react-native';
//Screens
import Header from './Shared/Header'
import ProductContainer from './Screens/Products/ProductContainer'
export default function App() {
return (
<View style={styles.container}>
<Header />
<ProductContainer />
</View>
);
}
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: '#fff',
alignItems: 'center',
justifyContent: 'center',
},
});
package.json:
{
"name": "animal-feedmart",
"version": "1.0.0",
"main": "node_modules/expo/AppEntry.js",
"scripts": {
"start": "expo start",
"android": "expo start --android",
"ios": "expo start --ios",
"web": "expo start --web",
"eject": "expo eject"
},
"dependencies": {
"expo": "~44.0.0",
"expo-status-bar": "~1.2.0",
"native-base": "^3.3.7",
"react": "17.0.1",
"react-dom": "17.0.1",
"react-native": "0.64.3",
"react-native-base": "^1.1.0",
"react-native-safe-area-context": "^4.2.1",
"react-native-svg": "^12.3.0",
"react-native-web": "0.17.1"
},
"devDependencies": {
"#babel/core": "^7.12.9"
},
"private": true
}
Please can anyone help me solve this issue? Thanks in advance
in your app.js import NativeBaseProvider and wrap your other components with it
import { NativeBaseProvider } from 'native-base';
return (
<NativeBaseProvider>
{Your other components}
</NativeBaseProvider>
);
If you put in the native provider and it is still showing the error, please ensure to change your Header as native base removed it from v3 upward, use HStack instead and if you want to use the Header downgrade the native base version to v2.12.14
import { NativeBaseProvider } from 'native-base';
export default function App() {
return (
<NativeBaseProvider>
<View style={styles.container}>
<Header />
<ProductContainer />
<StatusBar style="auto" />
</View>
</NativeBaseProvider>
);
}
I have solved this in App.js
import { NavigationContainer } from '#react-navigation/native';
import { NativeBaseProvider, extendTheme } from 'native-base';
Create a Theme
const newColorTheme = {
brand: {
900: '#5B8DF6',
800: '#ffffff',
700: '#cccccc',
},
};
const theme = extendTheme({
colors: newColorTheme,
});
and use on
export default function App() {
return (
<NativeBaseProvider theme={theme}>
<NavigationContainer>
<Header />
<Main/>
</NavigationContainer>
</NativeBaseProvider>
);
}
Related
I'm trying to implement this custom drawer with animation effect while sliding (opening, closing), the MainLayout should be resizing with a shrinking / growing animation when toggeling the drawer but what it does is simply changing it's size after it reache the right or left end, infact if I'm using the close button insted of pull / push through touch, upon returning it isn't growing in full sceen.
Code for Drawer:
import 'react-native-gesture-handler';
import React, {useState} from 'react';
import {StyleSheet, TouchableOpacity, Image, Text, View} from 'react-native';
import LinearGradient from 'react-native-linear-gradient';
import Animated from 'react-native-reanimated';
import {
createDrawerNavigator,
DrawerContentScrollView,
useDrawerProgress,
} from '#react-navigation/drawer';
import {icons} from '../constants';
// screens import
import MainLayout from '../screens/MainLayout';
const Drawer = createDrawerNavigator();
const CustomDrawerItem = ({icon, label}) => {
return (
<TouchableOpacity // drawer item button
style={[styles.drawerItem]}
onPress={() => console.log('drawer item')}>
<Image // drawer item icon
source={icon}
style={styles.drawerItemIcon}
/>
<Text // drawer item label
style={styles.drawerItemLabel}>
{label}
</Text>
</TouchableOpacity>
);
};
const CustomDrawerContent = ({navigation}) => {
return (
<DrawerContentScrollView
scrollEnabled={true}
contentContainerStyle={{flex: 1}}>
<View style={{flex: 1, paddingHorizontal: 20}}>
<View // close button container
style={styles.closeBtnContainer}>
<TouchableOpacity // close button
style={styles.closeBtn}
onPress={() => navigation.closeDrawer()}>
<Image // close button icon
source={icons.close}
style={styles.closeBtnIcon}
resizeMode="contain"
/>
</TouchableOpacity>
</View>
<TouchableOpacity // profile button
style={styles.profileButton}
onPress={() => console.log('profile')}>
<Image // profile image
source={icons.avatar}
style={styles.profileImage}
resizeMode="cover"
/>
<View // profile text container
style={{marginLeft: 10}}>
<Text // profile name
style={styles.commonTxt}>
John Doe
</Text>
<Text // profile email
style={[styles.commonTxt, {fontSize: 15}]}>
john#xyz.com
</Text>
</View>
</TouchableOpacity>
<View // drawer items container
style={styles.drawerItmContainer}>
<CustomDrawerItem // qr code
icon={icons.qr_code}
label="QR Code"
/>
<CustomDrawerItem // resource
icon={icons.resource}
label="Resource"
/>
<CustomDrawerItem // collection report
icon={icons.collection_report}
label="Collection Report"
/>
<CustomDrawerItem // change pin
icon={icons.change_pin}
label="Change Pin"
/>
<View // separator
style={styles.separator}
/>
</View>
<View // logout button container
style={{marginBottom: 20}}>
<CustomDrawerItem // logout
icon={icons.logout}
label="Logout"
/>
</View>
</View>
</DrawerContentScrollView>
);
};
const CustomDrawer = () => {
return (
<LinearGradient
colors={['#ff9933', '#3b5998', '#192f6a']}
style={styles.container}>
<Drawer.Navigator
screenOptions={{
headerShown: false,
drawerType: 'slide',
overlayColor: 'transparent',
drawerStyle: {flex: 1, width: '65%', backgroundColor: 'transparent'},
sceneContainerStyle: {backgroundColor: 'transparent'},
}}
drawerContent={props => {
return <CustomDrawerContent navigation={props.navigation} />;
}}
initialRouteName="MainLayout">
<Drawer.Screen name="MainLayout">
{props => <MainLayout {...props} />}
</Drawer.Screen>
</Drawer.Navigator>
</LinearGradient>
);
};
export default CustomDrawer;
const styles = StyleSheet.create({
drawerItem: {
flexDirection: 'row',
alignItems: 'center',
marginBottom: 20,
alignItems: 'center',
borderRadius: 10,
},
drawerItemIcon: {width: 20, height: 20, tintColor: '#fff'},
drawerItemLabel: {fontSize: 18, color: '#fff', marginLeft: 15},
profileButton: {flexDirection: 'row', alignItems: 'center', marginTop: 20},
profileImage: {width: 50, height: 50, borderRadius: 10},
closeBtnContainer: {alignItems: 'flex-start', justifyContent: 'center'},
closeBtn: {alignItems: 'center', justifyContent: 'center'},
closeBtnIcon: {width: 30, height: 30, tintColor: '#fff'},
commonTxt: {fontSize: 18, color: '#fff'},
drawerItmContainer: {flex: 1, marginTop: 20},
separator: {height: 1, backgroundColor: '#fff', marginVertical: 10},
container: {flex: 1, backgroundColor: '#ff9f1c'},
});
Code for MainLayout:
import 'react-native-gesture-handler';
import {StyleSheet, Text, View, SafeAreaView} from 'react-native';
import React from 'react';
import Animated from 'react-native-reanimated';
import {useDrawerProgress} from '#react-navigation/drawer';
const MainLayout = props => {
const progress = useDrawerProgress();
const scale = Animated.interpolateNode(progress.value, {
inputRange: [0, 1],
outputRange: [1, 0.75],
});
const borderRadius = Animated.interpolateNode(progress.value, {
inputRange: [0, 1],
outputRange: [0, 30],
});
const animatedStyle = {
borderRadius,
transform: [{scale}],
};
return (
<Animated.View
style={{
flex: 1,
alignItems: 'center',
justifyContent: 'center',
backgroundColor: '#fff',
...animatedStyle,
}}>
<Text>MainLayout</Text>
</Animated.View>
);
};
export default MainLayout;
const styles = StyleSheet.create({});
Animation Issue:
Closing Issue:
package.json
{
"name": "Dhananjaya",
"version": "0.0.1",
"private": true,
"scripts": {
"android": "react-native run-android",
"ios": "react-native run-ios",
"start": "react-native start",
"test": "jest",
"lint": "eslint ."
},
"dependencies": {
"#react-native-masked-view/masked-view": "^0.2.6",
"#react-navigation/drawer": "^6.4.1",
"#react-navigation/native": "^6.0.10",
"#react-navigation/stack": "^6.2.1",
"axios": "^0.27.2",
"native-base": "^3.4.5",
"react": "17.0.2",
"react-native": "0.68.2",
"react-native-gesture-handler": "^2.4.2",
"react-native-linear-gradient": "^2.5.6",
"react-native-reanimated": "^2.8.0",
"react-native-safe-area-context": "^4.2.5",
"react-native-screens": "^3.13.1",
"react-native-svg": "^12.3.0"
},
"devDependencies": {
"#babel/core": "7.18.2",
"#babel/runtime": "7.18.3",
"#react-native-community/eslint-config": "2.0.0",
"babel-jest": "26.6.3",
"eslint": "7.32.0",
"jest": "26.6.3",
"metro-react-native-babel-preset": "0.67.0",
"react-test-renderer": "17.0.2"
},
"jest": {
"preset": "react-native"
}
}
babel.config.js
(for reference to reanimated configuration)
module.exports = {
presets: ['module:metro-react-native-babel-preset'],
plugins: ['react-native-reanimated/plugin'],
};
Looks like I fixed the problem, I just had to add "useLegacyImplementation" inside screenOptions prop of Drawer, Thats it.
<Drawer.Navigator
detachInactiveScreens={true}
// backBehavior="history"
screenOptions={{
headerShown: false,
drawerType: 'slide',
overlayColor: 'transparent',
drawerStyle: {flex: 1, width: '65%', backgroundColor: 'transparent'},
sceneContainerStyle: {backgroundColor: 'transparent'},
}}
drawerContent={props => {
return <CustomDrawerContent navigation={props.navigation} />;
}}
useLegacyImplementation // <-- THIS LINE
initialRouteName="Tabs">
<Drawer.Screen
name="Tabs"
component={Tabs}
options={{unmountOnBlur: true}}
/>
<Drawer.Screen
name="Profile"
component={Profile}
options={{unmountOnBlur: true}}
/>
<Drawer.Screen
name="Map"
component={Map}
options={{unmountOnBlur: true}}
/>
</Drawer.Navigator>
I have a react webapp that I'd like have to render a pdf and email it when a button is pushed. For testing sake, when the button is pushed in the react frontend, it sends a request to my expressjs backend and attempts to generate a static pdf through #react-pdf/renderer.
I don't have a clear understanding of ES Modules vs CommonJS, but my server was using CommonJS, so I added "type": "module" to the server's package.json and updated the imports in server.js. However, the compiler complains about SyntaxError: Unexpected token '<' in server.js and materials.js (depending on setup). What am I doing wrong?
(code below has been cleaned to anonymize)
Edit
Here is an example of react-pdf/renderer being used on Node
server.js:
// const express = require('express');
// const cors = require('cors');
// const fs = require('fs')
// const react = require('react')
// const reactpdf = require('#react-pdf/renderer');
// const materials = require('./pdf/src/materials');
import express from 'express';
import cors from 'cors';
import fs from 'fs';
import react from 'react';
import ReactPDF from '#react-pdf/renderer';
import MaterialsList from './materials.js';
const app = express();
const port = 5000;
app.use(cors())
app.use(express.urlencoded());
app.use(express.json());
app.listen(port, function () {
console.log(`server running on http://localhost:${port}`);
})
app.post('/sendmaterials', cors(), function (req, res) {
// const pdf = req.body;
// console.log(pdf);
// reactpdf.render(pdf, `${__dirname}/trial.pdf`);
reactpdf.render(<MaterialsList />, `${__dirname}/trial.pdf`);
// fs.writeFile('trial.pdf', pdf, (err) => {
// // throws an error, you could also catch it here
// if (err) throw err;
// // success case, the file was saved
// console.log('PDF saved!');
// });
})
package.json:
{
"name": "app",
"version": "1.0.0",
"description": "",
"main": "index.js",
"type": "module",
"dependencies": {
"#react-pdf/renderer": "^1.6.13",
"concurrently": "^5.3.0",
"cors": "^2.8.5",
"express": "^4.17.1",
"firebase": "^9.0.0-beta.1",
"nodemon": "^2.0.6",
"react": "^17.0.2"
},
"devDependencies": {
"husky": "^5.1.3",
"lint-staged": "^10.5.4",
"prettier": "^2.2.1",
"pretty-quick": "^3.1.0"
},
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1",
"start": "concurrently \"nodemon server.js\" \"cd frontend && yarn start\"",
"init": "concurrently \"yarn\" \"cd frontend && yarn\"",
"install-initial": "concurrently \"yarn install\" \"cd frontend && yarn install\"",
"start-frontend": "cd frontend && yarn start",
"start-server": "nodemon server.js",
"pretty-quick": "pretty-quick",
"prepare": "husky install"
},
"husky": {
"hooks": {
"pre-commit": "pretty-quick --staged"
}
},
"lint-staged": {
"linters": {
"src/**/*.{js,css}": [
"prettier --write",
"git add"
]
}
}
}
materials.js:
import React from 'react';
import {
Document,
Page,
Text,
View,
StyleSheet,
Image,
// Font,
} from '#react-pdf/renderer';
import Logo from './images/img.png'
// import Trebuchet from './fonts/Trebuchet/trebuchet-ms.ttf'
// Font.register({
// family: 'Trebuchet MS',
// src: Trebuchet,
// })
// Create styles
const styles = StyleSheet.create({
page: {
padding: 30,
},
container: {
marginTop: 20,
marginBottom: 20,
flex: 0,
flexDirection: 'row',
'#media max-width: 400': {
flexDirection: 'column',
},
},
image: {
marginTop: 20,
},
mainTitle: {
// fontFamily: 'Trebuchet MS',
paddingLeft: 15,
fontWeight: 'bold',
color: "#000000",
fontSize: 19,
},
title: {
// fontFamily: 'Trebuchet MS',
fontWeight: 'bold',
color: "#000000",
fontSize: 16,
textDecoration: 'underline',
},
regGrey: {
// fontFamily: 'Trebuchet MS',
color: "#8d8d8d",
fontSize: 12,
},
regBlack: {
// fontFamily: 'Trebuchet MS',
color: "#101010",
fontSize: 12,
marginBottom: 15,
},
column: {
flexDirection: 'column',
width: 180,
paddingLeft: 15,
paddingRight: 15,
'#media max-width: 400': {
width: '100%',
paddingRight: 0,
},
'#media orientation: landscape': {
width: 200,
},
},
table: {
width: '100%',
alignContent: 'center',
borderWidth: 0,
display: 'flex',
flexDirection: 'column',
paddingTop: 10,
},
header: {
backgroundColor: "#4c4c4c",
fontWeight: 'bold',
color: "#fdfdfd",
flexWrap: 'wrap'
},
tableRow:{
display: 'flex',
flexDirection: 'row',
},
lightRow:{
display: 'flex',
flexDirection: 'row',
backgroundColor: "#cfcfcf",
},
darkRow:{
display: 'flex',
flexDirection: 'row',
backgroundColor: "#aeaeae",
},
cell: {
fontColor: "#101010",
// fontFamily: 'Trebuchet MS',
fontSize: 12,
borderWidth: 0,
display: 'flex',
justifyContent: 'center',
alignContent: 'center',
textAlign: 'center',
flexWrap: 'wrap'
},
});
// Create table object
const Table = ({header, alternate, children, col}) => (
<View style={styles.table}>
{children.map((row, ind) =>
<View key={ind} style={[styles.tableRow,
header && ind === 0 ? styles.header: {},
alternate && ind % 2 === 0 && ind !== 0 ? styles.lightRow: {},
alternate && ind % 2 !== 0 && ind !== 0 ? styles.darkRow: {},
]}>
{row.map((cell, j) =>
<View key={j} style={[styles.cell, {width:col[j], height: 40}]}>
{
typeof(cell) === 'string' || typeof(cell) === 'number' ?
<Text>{cell}</Text> : cell
}
</View>
)}
</View>
)}
</View>
)
// Create Document Component
const MaterialsList = () => (
<Document>
<Page style={styles.page}>
<View style={styles.container}>
<View style={styles.column}>
<Text style={styles.title}>
Steels
</Text>
<Table
col={['60%', '40%']}
header
alternate
children={[
['Item', 'Quantity'],
['Steel', '10'],
['U Channel', '10'],
['Gate Insert', '10'],
]} />
</View>
</View>
</Page>
</Document>
);
export default MaterialsList
The problem was in the package.json file, I was missing the babel libraries and config file. I have a example repo showing the correct setup and a link to the discussion on the react-pdf/renderer github discussion.
I was building a website for developers following a Udemy course. It redirects users to the dashboard after they log in. I need to make the dashboard page private, so that only logged-in users can access it, therefore I put it in a private route. If a user signs out, I need to redirect the user to the sign in page using the privateroute function, however private route does not redirect it will stay on dashboard page, and when I type localhost://3000/dashboard I can access dashboard page without the user having to log in
I need your help to fix this
Thankyou in advance
dashboard components
import React from 'react';
import PropTypes from 'prop-types';
const Dashboard = props => {
return <div>Dashboard</div>;
};
Dashboard.propTypes = {};
export default Dashboard;
PrivateRoute components
import React from 'react';
import { Route, Redirect } from 'react-router-dom';
import PropTypes from 'prop-types';
import { connect } from 'react-redux';
const PrivateRoute = ({
component: Component,
auth: { isAuthenticated, loading },
...rest
}) => (
<Route
{...rest}
render={props =>
!isAuthenticated && !loading ? (
<Redirect to='/login' />
) : (
<Component {...props} />
)
}
/>
);
PrivateRoute.propTypes = {
auth: PropTypes.object.isRequired,
};
const mapStateToProps = state => ({
auth: state.auth,
});
export default connect(mapStateToProps)(PrivateRoute);
App.js
import React, { Fragment, useEffect } from 'react';
import './App.css';
import { BrowserRouter as Router, Route, Switch } from 'react-router-dom';
import Navbar from './components/layout/Navbar';
import Landing from './components/layout/Landing';
import Login from './components/auth/Login';
import Register from './components/auth/Register';
import Alert from './components/layout/Alert';
// Redux
import { Provider } from 'react-redux';
import store from './store';
import { loadUser } from './actions/auth';
import setAuthToken from './utils/setAuthToken';
import Dashboard from './components/dashboard/Dashboard';
import PrivateRoute from './components/routing/PrivateRoute';
if (localStorage.token) {
setAuthToken(localStorage.token);
}
const App = () => {
useEffect(() => {
store.dispatch(loadUser());
}, []);
return (
<Provider store={store}>
<Router>
<Fragment>
<Navbar />
<Route exact path='/' component={Landing} />
<section className='container'>
<Alert />
<Switch>
<Route exact path='/register' component={Register} />
<Route exact path='/login' component={Login} />
<PrivateRoute exact path='/dashboard' component={Dashboard} />
</Switch>
</section>
</Fragment>
</Router>
</Provider>
);
};
export default App;
**auth.js **
import {
REGISTER_SUCCESS,
REGISTER_FAIL,
USER_LOADED,
AUTH_ERROR,
LOGIN_FAIL,
LOGIN_SUCCESS,
LOGOUT,
} from '../actions/types';
const initialState = {
token: localStorage.getItem('token'),
isAuthenticated: null,
loading: true,
user: null,
};
export default function (state = initialState, action) {
const { type, payload } = action;
switch (type) {
case USER_LOADED:
return {
...state,
isAuthenticated: true,
loading: false,
user: payload,
};
case REGISTER_SUCCESS:
case LOGIN_SUCCESS:
localStorage.setItem('token', payload.token);
return {
...state,
...payload,
isAuthenticated: true,
loading: false,
};
case REGISTER_FAIL:
case AUTH_ERROR:
case LOGIN_FAIL:
case LOGOUT:
localStorage.removeItem('token');
return {
...state,
token: null,
isAuthenticated: false,
loading: false,
};
default:
return state;
}
}
package.json in client side
{
"name": "client",
"version": "0.1.0",
"private": true,
"dependencies": {
"#testing-library/jest-dom": "^5.16.1",
"#testing-library/react": "^12.1.2",
"#testing-library/user-event": "^13.5.0",
"axios": "^0.24.0",
"react": "^17.0.2",
"react-dom": "^17.0.2",
"react-redux": "^6.0.0",
"react-router-dom": "^4.3.1",
"react-scripts": "5.0.0",
"redux": "^4.1.2",
"redux-devtools-extension": "^2.13.9",
"redux-thunk": "^2.4.1",
"uuid": "^8.3.2",
"web-vitals": "^2.1.3"
},
"scripts": {
"start": "react-scripts start",
"build": "react-scripts build",
"test": "react-scripts test",
"eject": "react-scripts eject"
},
"eslintConfig": {
"extends": [
"react-app",
"react-app/jest"
]
},
"browserslist": {
"production": [
">0.2%",
"not dead",
"not op_mini all"
],
"development": [
"last 1 chrome version",
"last 1 firefox version",
"last 1 safari version"
]
},
"proxy": "http://localhost:5000"
}
It was a loading issue. The loading value does not change. The value remained true,
Therefore, I removed the loading check from the render. This worked.
const PrivateRoute = ({
component: Component,
auth: { isAuthenticated },
...rest
}) => (
<Route
{...rest}
render={props =>
!isAuthenticated ? (
<Redirect to='/login' />
) : (
<Component {...props} />
)
}
/>
);
Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 4 years ago.
Improve this question
I am new working with React Native and Expo XDE, I am implementing the PropTypes in the file TaskList.js of type arrayOf but at the time of compiling the application I get an error indicating "undefined is not an object (evaluating 'react3.default.PropTypes.arrayOf ') "and even if I add another PropTypes of type String or another the same thing happens.
How can I solve this problem with the PropTypes?
Error
package.json
{
"name": "test",
"version": "0.1.0",
"private": true,
"devDependencies": {
"react-native-scripts": "1.11.1",
"jest-expo": "25.0.0",
"react-test-renderer": "16.2.0"
},
"main": "./node_modules/react-native-scripts/build/bin/crna-entry.js",
"scripts": {
"start": "react-native-scripts start",
"eject": "react-native-scripts eject",
"android": "react-native-scripts android",
"ios": "react-native-scripts ios",
"test": "node node_modules/jest/bin/jest.js"
},
"jest": {
"preset": "jest-expo"
},
"dependencies": {
"expo": "^25.0.0",
"react": "16.2.0",
"react-native": "0.52.0"
}
}
App.js
import React from 'react';
import { StyleSheet, Text, View, ListView } from 'react-native';
import TaskList from './TaskList';
export default class App extends React.Component {
constructor(props, context){
super(props, context);
this.state = {
todos:[
{
task : "Learn React Native"
},
{
task : "Learn Redux"
},
]
}
}
render() {
return (
<View style={styles.container}>
<TaskList todos={this.state.todos}/>
</View>
);
}
}
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: '#fff',
alignItems: 'center',
justifyContent: 'center',
},
});
TaskList.js
import React, {Component, PropTypes} from 'react';
import {View, Text, Button, ListView} from 'react-native';
class TaskList extends React.Component {
constructor(props, context){
super(props, context);
const ds = new ListView.DataSource({rowHasChanged: (r1, r2) => r1 !== r2});
this.state = {
dataSource: ds.cloneWithRows(props.todos),
}
}
renderRow =(todo)=>{
return(
<Text>{todo.task}</Text>
)
}
render(){
return(
<View>
<ListView
dataSource={this.state.dataSource}
key={this.props.todos}
renderRow={this.renderRow.bind(this)}
/>
</View>
)
}
}
TaskList.propTypes = {
todos: React.PropTypes.arrayOf(React.PropTypes.object).isRequired,
}
export default TaskList;
PropTypes were moved into their separate NPM package (v15+), prop-types and no longer exist on the React package. That's why it is reported as undefined. Install it and import:
import PropTypes from 'prop-types';
You need to add the dependency
npm install --save prop-types
This command install prop-types in your project. Check your package.json file in your project
"dependencies": {
"prop-types": "^15.6.1"
}
And import it on your project where you want to use. by importing following package
import PropTypes from 'prop-types'; // ES6
Maybe I am just not using axios correctly but I currently have a react front-end and node.js back end.
I am trying to POST to my api endpoint "/api/:id/addItem" but nothing is logging when making the request.
Here is my code:
ListForm component ->
import React from 'react';
import * as helpers from '../helpers';
class ListForm extends React.Component {
state = {
value: ''
}
handSubmit = e => {
e.preventDefault();
helpers.addItem(this.props.currentUser.googleId, this.state.value);
this.setState({value: ''});
}
render() {
return (
<form onSubmit={this.handleSubmit}>
<input type="text"
value={this.state.value}
onChange={e => this.setState({value: e.target.value})}
/>
<button>Add item</button>
</form>
);
}
}
export default ListForm;
Routes ->
const mongoose = require('mongoose');
const User = require('../models/userSchema');
module.exports = (app) => {
app.post('/api/:id/addItem', (req, res) => {
console.log('HEY!');
});
};
helpers.js ->
import axios from 'axios';
export const fetchUser = async () => {
const resp = await axios.get('/api/current_user');
return resp.data;
}
export const addItem = async (id, newItem) => {
const resp = await axios.post("/api/" + id + "/addItem", newItem);
return resp.data;
}
Package.json to show forwarding requests->
{
"name": "client",
"version": "0.1.0",
"private": true,
"proxy": {
"/auth/google": {
"target": "http://localhost:5000"
},
"/api/*": {
"target": "http://localhost:5000"
}
},
"dependencies": {
"axios": "^0.17.1",
"react": "^16.2.0",
"react-dom": "^16.2.0",
"react-scripts": "1.0.17"
},
"scripts": {
"start": "react-scripts start",
"build": "react-scripts build",
"test": "react-scripts test --env=jsdom",
"eject": "react-scripts eject"
}
}
Issue here is with newItem , its not json it's just simple value
axios.post("/api/" + id + "/addItem", newItem);
It should be like :
axios.post("/api/" + id + "/addItem", {value : newItem});
Or pass json from addItem :
helpers.addItem(this.props.currentUser.googleId, this_should_be_json );