React Router and TypeScript Implementation - javascript

What is the proper way to wire typescript and react-router together when using render prop and a lambda function to pass state and props to child components?
I'm on a super rocky road trying to wire React Router to TypeScript.
I need to pass props and state from my parent component to its children
rendered by React Router. To do so I'm using the render prop as explained here
To fix:
Lambdas are forbidden in JSX attributes due to their rendering performance impact
I wrote a separate method to fix the Lambda error and passed it to render in Route i.e:
public gameRoute = (props: any, state: object) => {
return <Game {...props} {...this.state} />
}
public render(): JSX.Element {
const { person, loading, error } = this.state
return (
<BrowserRouter>
<div className="App">
<ul>
<li>
<Link to="/">home</Link>
</li>
<li>
<Link to="/play-game">Play Game!</Link>
</li>
</ul>
<Switch>
<Route path="/play-game" render={this.gameRoute} />
</Switch>
</div>
</BrowserRouter>
)
}
The main problem is that TypeScript errors:
Trying to work around TypeScript and React Router errors, I added the following types to my child component:
// Child Component
import React from 'react'
import { RouteComponentProps } from 'react-router-dom'
interface GameProps extends RouteComponentProps<any>, React.Props<any> {
person: object[] | any
loading: boolean | string
error: null
}
export const Game: React.SFC<GameProps> = ({ person }) => (
<p className="error">Game is ON! {person}</p>
)
Then I wrote types to my parent component i.e:
// Parent Compoment
import React, { Component } from 'react'
import { StaticContext } from 'react-router'
import { BrowserRouter, Link, Route, RouteComponentProps, Switch } from 'react-router-dom'
import './App.css'
import { Error } from './Error/Error'
import { Game } from './Game/Game'
import { Loading } from './Loading/Loading'
interface AppProps extends RouteComponentProps<any> { }
interface AppState {
person: object[]
loading: boolean | string
error: null
}
export default class App extends Component<AppProps, AppState> {
public state = {
error: null,
loading: true,
person: [],
}
public async componentDidMount() {
const url = 'myApi'
try {
const res = await fetch(url)
const data = await res.json()
this.setState({ person: data, loading: false })
} catch (error) {
this.setState({ error, loading: false })
console.error(error)
}
}
public gameRoute = (props: any, state: object) => {
return <Game {...props} {...this.state} />
}
public render(): JSX.Element {
const { person, loading, error } = this.state
return (
<BrowserRouter>
<div className="App">
<ul>
<li>
<Link to="/">home</Link>
</li>
<li>
<Link to="/play-game">Play Game!</Link>
</li>
</ul>
<Switch>
<Route path="/play-game" render={this.gameRoute} />
</Switch>
</div>
</BrowserRouter>
)
}
}
I'm flying in the dark here so your guidance would be much appreciated
Here's my package.json just in case:
{
"name": "my-app",
"version": "0.1.0",
"private": true,
"dependencies": {
"#types/jest": "^23.3.12",
"#types/node": "^10.12.18",
"#types/react": "^16.7.18",
"#types/react-dom": "^16.0.11",
"#types/react-router": "^4.4.3",
"#types/react-router-dom": "^4.3.1",
"react": "^16.7.0",
"react-dom": "^16.7.0",
"react-router-dom": "^4.3.1",
"react-scripts": "2.1.3",
"typescript": "^3.2.2"
},
"scripts": {
"start": "react-scripts start",
"build": "react-scripts build",
"test": "react-scripts test",
"eject": "react-scripts eject",
"tslint-check": "tslint-config-prettier-check ./tslint.json",
"lint": "tslint -c tslint.json src/**/*.{ts,tsx} --fix --format verbose"
},
"eslintConfig": {
"extends": "react-app"
},
"browserslist": [
">0.2%",
"not dead",
"not ie <= 11",
"not op_mini all"
],
"devDependencies": {
"tslint": "^5.12.1",
"tslint-config-prettier": "^1.17.0",
"tslint-plugin-prettier": "^2.0.1",
"tslint-react": "^3.6.0"
}
}

Related

CardElement not showing ui components in react app ie `Card Number, MM/YY, CVC?

So my problem is that I cannot see the CardElement Ui component in the image below. It should be above the Order Total: $0 which is beside the payment method.
I have tried many other ways of debugging it but no luck. As of posting this, I am still debugging it and external help from experienced developers would be appreciated. I will provide my code below ie Payment.js Payment.css App.js
this is Payment.js
import React, { useState, useEffect } from "react";
import "./Payment.css";
import { useStateValue } from "./StateProvider";
import CheckoutProduct from "./CheckoutProduct";
import { Link, useNavigate } from "react-router-dom";
import { CardElement, useStripe, useElements } from "#stripe/react-stripe-js";
import CurrencyFormat from "react-currency-format";
import { getBasketTotal } from "./reducer";
import axios from "./axios";
function Payment() {
const [{ basket, user }, dispatch] = useStateValue();
const navigate = useNavigate();
const stripe = useStripe();
const elements = useElements();
const [succeeded, setSucceeded] = useState(false);
const [processing, setProcessing] = useState("");
const [error, setError] = useState(null);
const [disabled, setDisabled] = useState(true);
const [clientSecret, setClientSecret] = useState(true);
useEffect(() => {
// generate the special stripe secret which allows us to charge a customer
const getClientSecret = async () => {
const response = await axios({
method: "post",
// Stripe expects the total in a currencies sub-units
url: `/payments/create?total=${getBasketTotal(basket) * 100}`,
});
setClientSecret(response.data.clientSecret);
};
getClientSecret();
}, [basket]);
const handleSubmit = async (event) => {
// do all the fancy stripe stuff...
event.preventDefault();
setProcessing(true);
const payload = await stripe
.confirmCardPayment(clientSecret, {
payment_method: {
card: elements.getElement(CardElement),
},
})
.then(({ paymentIntent }) => {
// paymentIntent = payment confirmation
setSucceeded(true);
setError(null);
setProcessing(false);
dispatch({
type: "EMPTY_BASKET",
});
navigate.replace("/orders");
});
};
const handleChange = (event) => {
// Listen for changes in the CardElement
// and display any errors as the customer types their card details
setDisabled(event.empty);
setError(event.error ? event.error.message : "");
};
return (
<div className="payment">
<div className="payment__container">
<h1>
Checkout (<Link to="/checkout">{basket?.length} items</Link>)
</h1>
<div className="payment__section">
<div className="payment__title">
<h3>Delivery Address</h3>
</div>
<div className="payment__address">
<p>{user?.email}</p>
<p>123 React Lane</p>
<p>Los Angeles, CA</p>
</div>
</div>
<div className="payment__section">
<div className="payment__title">
<h3>Review items and delivery</h3>
</div>
<div className="payment__items">
{basket.map((item) => (
<CheckoutProduct
id={item.id}
title={item.title}
image={item.image}
price={item.price}
rating={item.rating}
/>
))}
</div>
</div>
<div className="payment__section">
<div className="payment__title">
<h3>Payment Method</h3>
</div>
<div className="payment__details">
<form onSubmit={handleSubmit}>
<CardElement onChange={handleChange} />
<div className="payment__priceContainer">
<CurrencyFormat
renderText={(value) => <h3>Order Total: {value}</h3>}
decimalScale={2}
value={getBasketTotal(basket)}
displayType={"text"}
thousandSeparator={true}
prefix={"$"}
/>
<button disabled={processing || disabled || succeeded}>
<span>{processing ? <p>Processing</p> : "Buy Now"}</span>
</button>
</div>
{error && <div>{error}</div>}
</form>
</div>
</div>
</div>
</div>
);
}
export default Payment;
this is Payment.css
.payment {
background-color: white;
}
.payment__container > h1 {
text-align: center;
padding: 10px;
font-weight: 400;
background-color: rgb(234, 237, 237);
border-bottom: 1px solid lightgray;
}
.payment__container > h1 a {
text-decoration: none;
}
.payment__section {
display: flex;
padding: 20px;
margin: 0 20px;
border-bottom: 1px solid lightgray;
}
.payment__title {
flex: 0.2;
}
.payment__address,
.payment__items,
.payment__details {
flex: 0.8;
}
this is App.js
import React, { useEffect } from "react";
import "./App.css";
import Header from "./Header";
import Home from "./Home";
import { BrowserRouter as Router, Routes, Route } from "react-router-dom";
import Checkout from "./Checkout";
import Login from "./Login";
import Payment from "./Payment";
import { auth } from "./firebase.js";
import { useStateValue } from "./StateProvider";
import { loadStripe } from "#stripe/stripe-js";
import { Elements } from "#stripe/react-stripe-js";
const stripePromise = loadStripe(
"pk_test_51Ku8iiSHAST6F5x2egU8YwHdYkqKAOcJIfrfXKa0b7kxeHm0ECkvFOLVW0KeaiudzfAfU31m954rOkIKGsoXhiAE00EQx04Did"
);
function App() {
const [{}, dispatch] = useStateValue();
useEffect(() => {
// will only run once when the app component loads...
auth.onAuthStateChanged((authUser) => {
console.log("THE USER IS >>> ", authUser);
if (authUser) {
// the user just logged in / the user was logged in
dispatch({
type: "SET_USER",
user: authUser,
});
} else {
// the user is logged out
dispatch({
type: "SET_USER",
user: null,
});
}
});
}, []);
return (
//BEM
<Router>
<div className="app">
<Routes>
<Route path="/login" element={[<Login />]} />
<Route path="/checkout" element={[<Header />, <Checkout />]} />
<Route
path="/payment"
element={[
<Header />,
<Elements stripe={stripePromise}>
<Payment />
</Elements>,
]}
/>
<Route path="/" element={[<Header />, <Home />]} />
</Routes>
</div>
</Router>
);
}
export default App;
//npm install <package-name> --legacy-peer-deps
this is Package.json of the src folder
{
"name": "amazon-clone",
"version": "0.1.0",
"private": true,
"dependencies": {
"#emotion/react": "^11.9.0",
"#emotion/styled": "^11.8.1",
"#mui/icons-material": "^5.6.1",
"#mui/material": "^5.6.1",
"#stripe/react-stripe-js": "^1.7.2",
"#stripe/stripe-js": "^1.29.0",
"#testing-library/jest-dom": "^5.16.4",
"#testing-library/react": "^13.1.1",
"#testing-library/user-event": "^13.5.0",
"axios": "^0.27.2",
"firebase": "^9.6.11",
"react": "^18.0.0",
"react-dom": "^18.0.0",
"react-router-dom": "^6.3.0",
"react-scripts": "5.0.1",
"web-vitals": "^2.1.4"
},
"scripts": {
"start": "set PORT=3000 && 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"
]
}
}
One last thing could anyone write why express is not working with node v.17 / 18 current version while writing this post it is express is not supported if I downgrade to node v16 will it cause trouble to other js code in my project. Please explain
package.json of the function folder
{
"name": "functions",
"description": "Cloud Functions for Firebase",
"scripts": {
"lint": "eslint .",
"serve": "firebase emulators:start --only functions",
"shell": "firebase functions:shell",
"start": "npm run shell",
"deploy": "firebase deploy --only functions",
"logs": "firebase functions:log"
},
"engines": {
"node": "16"
},
"main": "index.js",
"dependencies": {
"cors": "^2.8.5",
"express": "^4.18.1",
"firebase-admin": "^10.0.2",
"firebase-functions": "^3.18.0",
"stripe": "^8.219.0"
},
"devDependencies": {
"eslint": "^8.9.0",
"eslint-config-google": "^0.14.0",
"firebase-functions-test": "^0.2.0"
},
"private": true
}
In some tutorial videos I can see they get it very quickly I don't know why I cannot debug. Kindly help me find the problem here. Thank you
In your App.js file, where you declare your Route to /payment, try to pass a single component, instead of passing your component already wrapped in <Elements> component.
I've faced this problem and for some reason, Stripe elements won't work that way. So instead try to make a component that will render your Payment component wrapped in <Elements>, I'll write some pseudocode for you:
ParentComponent.js
const ParentComponent = () => {
return (
<Elements>
<Payments />
</Elements>
);
}
So now, you would just do this in your App.js component:
App.js
<Route
path="/payment"
element={[
<Header />,
<ParentComponent />
]}
/>
I was finally able to find a proper solution.
Older versions of stripe/react-stripe-js are not working with react18. To solve issue, please install latest version of react-stripe-js.
npm install stripe/react-stripe-js#latest
Worked for me.

React routing cannot read pathname property on navigation

I have recently started developing frontend apps with React and I come from a little programming experience with react-native.
To improve my knowledge on react I studied both the official documentation and took courses on udemy.
So I'm building a small test app in which to use react routing (following what we saw in the udemy course).
However, I have the following error related to routing (I attach the error screen)
I have searched here on the stack that online for possible solutions, such as downgrading react-router-dom, or modifying the history declaration, but unfortunately I still get this error and I can't understand what it comes from.
Do you have any suggestions or advice?
My app configuration:
package.json
"name": "app1",
"version": "0.1.0",
"private": true,
"dependencies": {
"#reduxjs/toolkit": "^1.8.1",
"#testing-library/jest-dom": "^5.16.4",
"#testing-library/react": "^12.1.4",
"#testing-library/user-event": "^13.5.0",
"history": "^5.3.0",
"react": "^18.0.0",
"react-dom": "^18.0.0",
"react-redux": "^7.2.8",
"react-router": "^6.3.0",
"react-router-dom": "^6.3.0",
"react-scripts": "5.0.0",
"web-vitals": "^2.1.4"
},
"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"
]
}
}
routes.js
import React, { Component } from 'react';
import Component1 from './functional/component1';
import Component2 from './functional/component2';
import Component3 from './functional/component3';
//import container home-page
import Container1 from './containers/container1';
import Header from './containers/header';
import history from './utils/history';
//react router import
import { Router, Route } from 'react-router';
class Routes extends Component {
render() {
return (
<div>
<Router history={history.location} navigator={history} >
<div>
<Header />
<Route path="/" component={Container1} />
<Route path="/component1" component={Component1} />
<Route path="/component2" component={Component2} />
<Route path="/component3" component={Component3} />
</div>
</Router>
</div>
)
}
}
export default Routes;
-history.js
var createHistory = require('history').createBrowserHistory;
export default createHistory();
Issue
The low-level Router takes a few different props than it did in v5.
Router
declare function Router(
props: RouterProps
): React.ReactElement | null;
interface RouterProps {
basename?: string;
children?: React.ReactNode;
location: Partial<Location> | string; // <-- required
navigationType?: NavigationType;
navigator: Navigator; // <-- required
static?: boolean;
}
Router source
export function Router({
basename: basenameProp = "/",
children = null,
location: locationProp, // <-- undefined location
navigationType = NavigationType.Pop,
navigator,
static: staticProp = false,
}: RouterProps): React.ReactElement | null {
...
let {
pathname = "/", // <-- cannot read "pathname" of undefined!
search = "",
hash = "",
state = null,
key = "default",
} = locationProp;
...
if (location == null) {
return null;
}
return (
<NavigationContext.Provider value={navigationContext}>
<LocationContext.Provider
children={children}
value={{ location, navigationType }}
/>
</NavigationContext.Provider>
);
}
You are incorrectly using a history prop instead of the location prop, and this is why location is undefined in the component and unable to read a pathname.
Additionally, in react-router-dom#6 the Route components necessarily need to be wrapped in the Routes component in order for route path matching and rendering to work.
Solution
Pass the correct required props and wrap the Route components in Routes component.
import React, { Component } from 'react';
import Component1 from './functional/component1';
import Component2 from './functional/component2';
import Component3 from './functional/component3';
//import container home-page
import Container1 from './containers/container1';
import Header from './containers/header';
import history from './utils/history';
//react router import
import { Router, Routes, Route } from 'react-router';
class Routes extends Component {
render() {
return (
<div>
<Router location={history.location} navigator={history} >
<div>
<Header />
<Routes>
<Route path="/" component={Container1} />
<Route path="/component1" component={Component1} />
<Route path="/component2" component={Component2} />
<Route path="/component3" component={Component3} />
</Routes>
</div>
</Router>
</div>
)
}
}
You are using react router v6 and in v6 you have to wrap all of your route's in <Routes>...</Routes> tag.
//react router import
import { Router, Route, Routes } from 'react-router'; // Make sure to import ----Routes----
class Routes extends Component {
render() {
return (
<div>
<Router history={history.location} navigator={history} >
<div>
<Header />
<Routes>
<Route path="/" component={Container1} />
<Route path="/component1" component={Component1} />
<Route path="/component2" component={Component2} />
<Route path="/component3" component={Component3} />
</Routes>
</div>
</Router>
</div>
)
}
}
export default Routes;
And you can't add anything between <Routes>...</Routes> except <Route />.

redux-form is not showing its all props values

i want to use all eventHandler of redux-form as show in sameple output image but its not coming as a props so i facing undefine error now what i can do to solve the issue
i have imported reducers in index.js file of src folder and create store
package.json
{
"name": "reactjs",
"version": "0.1.0",
"private": true,
"dependencies": {
"#material-ui/core": "^4.11.0",
"#material-ui/icons": "^4.9.1",
"prop-types": "^15.7.2",
"react": "^16.11.0",
"react-dom": "^16.11.0",
"react-router-dom": "^5.2.0",
"react-scripts": "3.2.0",
"react-transition-group": "^4.4.1",
"redux-form": "^8.3.6"
},
"scripts": {
"start": "react-scripts start",
"build": "react-scripts build",
"test": "react-scripts test",
"eject": "react-scripts eject"
}
}
reducers/index.js
import { reducer } from 'redux-form';
import { combineReducers } from "redux";
export default combineReducers({
reducer
})
TouristRegistration.js
import React, { Component } from 'react';
import { reduxForm, Field } from "redux-form";
import { Button } from "#material-ui/core"
import RegistrationField from "./ReaperComponent"
class TutiorsRegistrationForm extends Component {
handlenextpage = () => {
this.props.nextPage()
}
render() {
return (
<form>
<Field
type="text"
name="FirstName"
component={RegistrationField}
/>
<Button
color="primary"
variant="contained"
type="submit"
>Next
</Button>
</form>
);
}
}
const validate = (value) => {
const errors = {}
if (!value.FirstName) {
errors.FirstName = "Required"
}
console.log("error " + JSON.stringify(errors));
return errors;
}
export default reduxForm({
validate: validate,
form: 'TutiorsRegistrationForm'
})(TutiorsRegistrationForm);
RegistrationField.js
import React from 'react';
import { TextField } from "#material-ui/core"
const ReaperComponent = (props) => {
console.log("props " + JSON.stringify(props));
return (
<TextField />
);
}
export default ReaperComponent;
output
of instructor
output in my case
props {"input":{"name":"FirstName","value":""},"meta":{"active":false,"asyncValidating":false,"autofilled":false,"dirty":false,"form":"TutiorsRegistrationForm","invalid":false,"pristine":true,"submitting":false,"submitFailed":false,"touched":false,"valid":true,"visited":false}}

Props not passed down to children using React-Redux

I am following this tutorial on React-Redux and I stumbled upon error on 1st part of section "React Redux tutorial: asynchronous actions in Redux, the naive way".
Post.componentDidMount
src/js/components/Posts.js:12
9 |
10 | componentDidMount() {
11 | // calling the new action creator
> 12 | this.props.getData();
| ^ 13 | }
14 |
15 | render() {
My understanding is that props from store is not passed down from the App component to Posts component. I have repeated the steps several times but I still cannot see the exact culprit. The source code from Git works just fine. I noticed, there are difference between my local and that of the GIT repo.
This is my package.json
{
"name": "react-redux-study",
"version": "0.1.0",
"private": true,
"dependencies": {
"#testing-library/jest-dom": "^4.2.4",
"#testing-library/react": "^9.5.0",
"#testing-library/user-event": "^7.2.1",
"react": "^16.13.1",
"react-dom": "^16.13.1",
"react-scripts": "3.4.1"
},
"scripts": {
"start": "react-scripts start",
"build": "react-scripts build",
"test": "react-scripts test",
"eject": "react-scripts eject"
},
"eslintConfig": {
"extends": "react-app"
},
"browserslist": {
"production": [
">0.2%",
"not dead",
"not op_mini all"
],
"development": [
"last 1 chrome version",
"last 1 firefox version",
"last 1 safari version"
]
},
"devDependencies": {
"react-redux": "^7.2.0",
"redux": "^4.0.5"
}
}
And this is the package.json from the Git repo.
UPDATE: Added my App.js and Posts.js
App.js
import React from "react";
import List from "./List";
import Form from "./Form";
import { Post } from "./Posts";
const App = () => (
<>
<div>
<h2>Articles</h2>
<List />
</div>
<div>
<h2>Add a new article</h2>
<Form />
</div>
<div>
<h2>API posts</h2>
<Post />
</div>
</>
);
export default App;
Posts.js
import React, { Component } from "react";
import { connect } from "react-redux";
import { getData } from "../actions/index";
export class Post extends Component {
constructor(props) {
super(props);
}
componentDidMount() {
// calling the new action creator
this.props.getData();
}
render() {
return null;
}
}
export default connect(
null,
{ getData }
)(Post);
I can actually just move on and use the source code from Git but I do want to understand what is the exact issue.
Issue :
// posts.js
export class Post extends Component { // <---- First : Export
...
}
export default connect( // <----- Second : Export
null,
{ getData }
)(Post);
// inside app.js
// you are importing first import, not the default which is connecting to you store
import { Post } from "./Posts";
Solution :
Change this line
import { Post } from "./Posts";
To
// import the default one
import Post from "./Posts";
In app component
<Post getData={postdata} />
In Posts component you can get data like this.
componentDidMount() {
let posts=this.props.getData;
}

React Native Error - Invariant Violation: Element type is invalid

I am following a Udemy course to build a demo react native application. So far, the application consists of 3 components - App, AlbumList & AlbumDetail. The code for each is listed below.
App.js
import React, { Component } from 'react';
import View from 'react-native';
import AlbumDetail from './AlbumDetail'
import axios from 'axios';
class AlbumList extends Component {
constructor(props){
super(props)
this.state = { albums: [{"title": "one"}, {"title": "two"}] }
}
renderAlbums() {
return this.state.albums.map(album =>
<AlbumDetail key={album.title} album={album} />
);
}
render() {
return (
<View>
{ this.renderAlbums() }
</View>
);
}
}
export default AlbumList;
AlbumList.js
import React, { Component } from 'react';
import View from 'react-native';
import AlbumDetail from './AlbumDetail'
import axios from 'axios';
class AlbumList extends Component {
constructor(props){
super(props)
this.state = { albums: [{"title": "one"}, {"title": "two"}] }
}
renderAlbums() {
return this.state.albums.map(album =>
<AlbumDetail key={album.title} album={album} />
);
}
render() {
return (
<View>
{ this.renderAlbums() }
</View>
);
}
}
export default AlbumList;
AlbumDetail.js
import React from 'react';
import { View, Text } from 'react-native';
const AlbumDetail = (props) => {
return (
<View>
<Text>{props.album.title}</Text>
</View>
)
};
export default AlbumDetail;
package.json
{
"main": "node_modules/expo/AppEntry.js",
"scripts": {
"start": "expo start",
"android": "expo start --android",
"ios": "expo start --ios",
"eject": "expo eject"
},
"dependencies": {
"axios": "^0.18.0",
"expo": "^32.0.0",
"react": "16.5.0",
"react-native": "https://github.com/expo/react-native/archive/sdk-32.0.0.tar.gz"
},
"devDependencies": {
"babel-preset-expo": "^5.0.0"
},
"private": true
}
When I run npm start and launch the app in a mobile device(One Plus 3T running Android 8.0.0), I get the following error
Invariant Violation: Element type is invalid: expected a string (for built-in components) or a class/function (for composite components) but got: object.
This error is located at:
in AlbumList (created by App)
in RCTView (at View.js:44)
in App (at withExpoRoot.js:22)
...
...
I went through a few questions posted in StackOverflow and most of them refer to incorrect way of exporting and importing components. As far as I can see, I am exporting and importing components correctly here but still get the error.
Feel free to add a comment if you need more information. Any help debugging the issue is appreciated.
import statement is wrong here at App.js and AlbumDetail.js
change it with
import {View} from "react-native"

Categories