First of all, I like to apologize for writing such a long post.I'm new to react and redux and I have created an ecommerce app. After implementing redux, I'm getting this error.
./src/Main.js
36:12-26 './redux/configureStore' does not contain an export named 'ConfigureStore'.
My code:
index.js
import React from "react";
import ReactDOM from "react-dom";
import Main from "./Main";
import "./index.css";
import 'bootstrap/dist/css/bootstrap.css';
import {BrowserRouter} from 'react-router-dom';
ReactDOM.render((
<BrowserRouter>
<Main/>
</BrowserRouter>
)
,
document.getElementById("root")
);
Main.js
import React, { Component } from "react";
import 'bootstrap/dist/css/bootstrap.min.css';
import $ from 'jquery';
import Popper from 'popper.js';
import 'bootstrap/dist/js/bootstrap.bundle.min';
import { Route, Switch, withRouter} from 'react-router-dom';
import Navigation from "./components/topNavigation";
import Footer from "./components/Footer";
import Banner from "./components/Banner";
import PLPMenu from "./components/PLPMenu";
import PDP from "./components/PDP";
import Login from "./components/Login"
import Home from "./components/Home";
import { Provider } from 'react-redux';
import { ConfigureStore } from './redux/configureStore';
import {connect} from 'react-redux';
const mapStateToProps = state =>{
return {
topnavigation: state.topnavigation,
plpmenu: state.plpmenu,
pdpmenu : state.pdpmenu
}
}
const store = ConfigureStore();
class Main extends Component {
render() {
return (
<Provider store={store}>
<div>
<Login />
<Navigation />
<Switch>
<Route exact path="/" component={Home} />
<Route path="/Apparel/:category/:subCategory/:id" component={PLPMenu} />
<Route path="/Apparel/:product/:id" component={PDP} />
<Route path="/login" component={Login} />
<Route path="/Banner" component={Banner} />
<Route path="/Footer" component={Footer} />
</Switch>
</div>
</Provider>
)
}
}
export default withRouter(connect(mapStateToProps)(Main));
topNavigation.js
import React, { Component } from 'react';
import axios from 'axios';
import SubMenu from './subMenu';
class Navigation extends Component {
state = {
mainCategory: []
}
componentDidMount() {
axios.get('http://localhost:3030/topCategory')
.then(res => {
// console.log(res.data.express);
this.setState({
mainCategory: res.data.express.catalogGroupView
})
})
}
render() {
const { mainCategory } = this.props;
return (
<nav className="navbar navbar-expand-lg navbar-dark bg-dark mainmenu">
<a className="navbar-brand" href="#">iFashion</a>
<button className="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarNav" aria-controls="navbarNav" aria-expanded="false" aria-label="Toggle navigation">
<span className="navbar-toggler-icon"></span>
</button>
<div className="collapse navbar-collapse" id="navbarNav">
<ul className="navbar-nav ml-auto">
{
mainCategory.map(navList => (
<li className="nav-item dropdown" key={navList.uniqueID}>
<a className="nav-link dropdown-toggle" id="navbarDropdown" role="button" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">{navList.name} </a>
<ul className="dropdown-menu secondDropdown" aria-labelledby="navbarDropdown">
<SubMenu below={navList.catalogGroupView} />
</ul>
</li>
))
}
</ul>
</div>
</nav>
)
}
}
export default Navigation;
PLPMenu.js
import React, { Component } from "react";
import { Link } from "react-router-dom";
import Footer from "./Footer";
import axios from "axios";
class PLPMenu extends Component {
state = {
shoeCategory: []
};
fetchData = id => {
axios
.get(`http://localhost:3030/category/` + id)
.then(response => {
console.log(response.data.express.catalogEntryView);
this.setState({
shoeCategory: response.data.express.catalogEntryView
});
})
.catch(err => {
console.log(err);
});
};
componentDidMount() {
let { id } = this.props.match.params;
this.fetchData(id);
}
componentDidUpdate(prevProps) {
let currentId = this.props.match.params.id;
let previousId = prevProps.match.params.id;
if (currentId !== previousId) {
this.fetchData(currentId);
}
}
render() {
const { shoeCategory } = this.props;
const picUrl = "https://149.129.128.3:8443";
return (
<div>
<div className="container">
<div className="row">
{shoeCategory &&
shoeCategory.map(shoeList => {
return (
<div key={shoeList.uniqueID} className="col-md-4">
<h2 key={shoeList.uniqueID} />
<img className="plpImage" src={picUrl + shoeList.thumbnail} />
<Link to={`/Apparel/${shoeList.name}/${shoeList.uniqueID}`}>
<p className="pdp">{shoeList.name}</p>
</Link>
<p>
Price : {shoeList.price[0].value}{" "}
{shoeList.price[0].currency}
</p>
</div>
);
})}
</div>
</div>
<Footer/>
</div>
);
}
}
export default PLPMenu;
PDP.js
import React, { Component } from "react";
import { Route, Link, BrowserRouter } from "react-router-dom";
import axios from "axios";
class PDP extends Component {
state = {
pdpCategory: []
};
fetchData = id => {
axios
.get(`http://localhost:3030/product/` + id)
.then(response => {
console.log(response.data.express.catalogEntryView);
this.setState({ pdpCategory: response.data.express.catalogEntryView });
})
.catch(err => {
console.log(err);
});
};
componentDidUpdate(prevProps) {
let currentId = this.props.match.params.id;
let previousId = prevProps.match.params.id;
if (currentId !== previousId) {
this.fetchData(currentId);
}
}
componentDidMount() {
let { id } = this.props.match.params;
this.fetchData(id);
}
render() {
const { pdpCategory } = this.props;
console.log(pdpCategory);
const picUrl = "https://149.129.128.3:8443";
return (
<div>
<div className="container">
<div className="row">
{pdpCategory &&
pdpCategory.map(pdpList => {
return (
<div key={pdpList.uniqueID} className="col-md-4">
<h2 key={pdpList.uniqueID} />
<img className="pdpImage " src={picUrl + pdpList.thumbnail} />
<p>
Price : {pdpList.price[0].value}{" "}
{pdpList.price[0].currency}
</p>
<p>
Description: {pdpList.longDescription}
</p>
<button type="submit">Add to Cart</button>
</div>
);
})}
</div>
</div>
</div>
);
}
}
export default PDP;
For the redux to implement, I have created a redux folder inside ./src folder and have created two files reducer.js and configureStore.js
import PLPMenu from "../components/PLPMenu";
import PDP from "../components/PDP";
import Navigation from "../components/topNavigation";
export const initialState = {
topnavigation: Navigation,
plpmenu: PLPMenu,
pdpmenu : PDP
};
export const Reducer = ( state = initialState , action) => {
return state;
};
configureStore.js
import { createStore} from 'redux';
import {Reducer, initialState} from './reducer';
export const Configuration = () =>{
const store = createStore(
Reducer,
initialState,
);
return store;
}
I don't know where my code is getting wrong. There is only a single error in the console browser window, which I have shared above. Can anyone please help me on this or given an insight how to perfectly implement a redux store.
change import { ConfigureStore } from './redux/configureStore';
to
import { Configuration } from './redux/configureStore'; in Main.js
Related
I am building a mock e-commerce store using react and after laying the groundwork for the website, I installed the package react-use-cart (https://www.npmjs.com/package/react-use-cart) to handle the items being added to the cart and to be used in a checkout page. I wrapped my app in the Cart Provider that was given by the react-use-cart package and set up the cart functions on my product pages but now my app does not load anything on startup and gives me an invalid hook call error. I have tried wrapping the app in the index.js file with the provider as well and that gives the same error.
import React, { useState } from "react";
import './css/App.css';
import {
BrowserRouter,
Routes,
Route,
} from "react-router-dom";
import NavBar from "./components/NavBar"
import ProductsScreen from "./screens/ProductsScreen"
import ProductDetailScreen from "./screens/ProductDetailScreen"
import HomeScreen from "./screens/HomeScreen"
import LoginScreen from "./screens/LoginScreen"
import RegisterScreen from "./screens/RegisterScreen";
import CartScreen from "./screens/CartScreen"
import { CartProvider } from "react-use-cart";
const App = () => {
return (
<>
<BrowserRouter>
<CartProvider>
<NavBar />
<Routes>
<Route path='/' element={<HomeScreen/>}/>
<Route path='/products' element={<ProductsScreen/>}/>
<Route path='/product/:id' element={<ProductDetailScreen/>}/>
<Route path='/login' element={<LoginScreen/>}/>
<Route path='/register' element={<RegisterScreen/>}/>
<Route path='/cart' element={<CartScreen/>}/>
</Routes>
</CartProvider>
</BrowserRouter>
</>
)
}
export default App;
import { useState, useEffect }from 'react'
import { Link, useParams } from 'react-router-dom'
import axios from 'axios'
import "../css/ProductDetailScreen.css"
import { useCart } from "react-use-cart";
// import Slideshow from '../components/SlideShow'
const { addItem, updateItemQuantity } = useCart();
const ProductDetailScreen = ( {match} ) => {
const [product, setProduct] = useState({})
const { id } = useParams()
useEffect(() => {
const getProduct = async () => {
const { data } = await axios.get(`/api/products/${id}`)
setProduct(data)
}
getProduct()
}, [])
return (
<>
<Link to ='/products'>Go Back</Link>
<div className="wrapper">
<div className="detail-grid">
<div className='imgContainer'>
<img className='cover_img1' src={product.cover_img} alt='Videogame Cover Art'/>
<div className='carousel'>
{product.images?.map((image, index) => (
<img key={index} src={image} alt="Videogame Gameplay"></img>
))}
</div>
{/*Replace carousel div with actual image slideshow*/}
</div>
<div>
<div className='textContainer'>
<h1 className='title1'>{product.title}</h1>
<h3 className='descriptionHeader'>Description:</h3>
<p className='description1'>{product.description}</p>
<h3 className='developer1'>Developer: {product.developer}</h3>
<h3 className='publisher1'>Publisher: {product.publisher}</h3>
<h3 className='releaseDate1'>Release Date: {product.releaseDate}</h3>
<h3 className='genre1'>Genre: {product.genre}</h3>
</div>
<div className='checkOutContainer'>
<h3 className='price1'>Price: ${product.price}</h3>
<button onClick={() => updateItemQuantity(product.id, product.quantity - 1)}> - </button>
<span>{product.quantity}</span>
<button onClick={() => updateItemQuantity(product.id, product.quantity + 1)}> + </button>
<button onClick={() => addItem(product)} className='addCart' type='button'>Add to Cart</button>
</div>
</div>
</div>
</div>
</>
)
}
export default ProductDetailScreen
I just started learning/working with react router and got stuck with the very basic stuff.
If I am adding the <Route> , the enclosed component is not loading. Can anyone please help me on this. I even tried removing other components and just testing with route but then also it was not working
index.js :
import React from 'react';
import ReactDOM from 'react-dom';
import './index.css';
import App from './App';
import { Provider } from 'react-redux'
import store from './store/store'
import { BrowserRouter } from 'react-router-dom'
ReactDOM.render(
<React.StrictMode>
<BrowserRouter>
<Provider store={store}>
<App />
</Provider>
</BrowserRouter>
</React.StrictMode >,
document.getElementById('root')
);
App.js:
import './App.css';
import 'bootstrap/dist/css/bootstrap.css';
import 'bootstrap/dist/js/bootstrap.js';
import Header from './components/Header';
import ProductCard from './components/ProductCard';
import ProductPage from './components/ProductPage';
import Cart from './components/Cart';
import { useSelector } from 'react-redux';
import LoginForm from './components/LoginForm';
import { useState, useEffect } from 'react';
import { Route } from 'react-router-dom';
function App() {
const showCartOption = useSelector(state => state.cart.showCartOption);
const isAuthenticated = useSelector(state => state.auth.isAuthenticated);
return (
<div class="m-3 shadow p-2">
<Header></Header>
<div class="row" >
{(isAuthenticated && showCartOption) &&
<Route path="/products">
<ProductPage />
</Route>}
{(isAuthenticated && !showCartOption) &&
<Route path="/cart">
<Cart />
</Route>
}
{!isAuthenticated && <LoginForm></LoginForm>}
</div>
</div>
);
}
export default App;
ProductPage.js:
import { useEffect, useState } from "react";
import ProductCard from "./ProductCard";
function ProductPage() {
const [products, setProducts] = useState([]);
const productDescriptionLength = 75;
const productTitleLength = 15;
console.log("rendering : ");
console.log(products);
useEffect(() => {
console.log("fetching products");
const productResponse = fetch('https://fakestoreapi.com/products')
.then(res => {
return res.json();
})
.then(res => {
console.log("resolved response : ");
console.log(res);
const translatedResponse = res.map(product => {
return {
productId: product.id,
productTitle: product.title.substring(0, productTitleLength) + "...",
productPrice: product.price,
productDescription: product.description.substring(0, productDescriptionLength) + "...",
productImage: product.image
}
})
return translatedResponse;
})
.then(res => {
console.log(res);
setProducts(res);
});
}, [])
return (
<div className="row row-cols-1 row-cols-md-4 g-4">
{
products.length > 0 && products.map(product =>
<div class="col">
<ProductCard
productTitle={product.productTitle}
productPrice={product.productPrice}
productImage={product.productImage}
productDescription={product.productDescription}
/>
</div>
)
}
</div>
);
}
export default ProductPage;
cart.js:
import { useState } from "react";
import { useSelector } from "react-redux";
import CartCard from "./CartCard";
function Cart() {
const cartItems = useSelector(state => state.cart.cartItems);
console.log("cartItems : ");
console.log(cartItems);
return (
<div class="">
{cartItems.length === 0 && <p class="m-5 text-center fs-1 shadow">Your cart is empty. Happy Shopping !</p>}
{cartItems.length > 0 &&
cartItems.map(cartItem => {
return <CartCard
productTitle={cartItem.productTitle}
productPrice={cartItem.productPrice}
productDescription={cartItem.productDescription}>
</CartCard>
})
}
</div>
);
}
export default Cart;
I am able to see the navbar but none of the enclosed components in route
Your routes should be inside of a Switch component in react router v5.
Something like this:
function App() {
const showCartOption = useSelector((state) => state.cart.showCartOption);
const isAuthenticated = useSelector((state) => state.auth.isAuthenticated);
return (
<div class='m-3 shadow p-2'>
<Header></Header>
<div class='row'>
<Switch>
<Route path='/products'>
{isAuthenticated && showCartOption && <ProductPage />}
</Route>
<Route path='/cart'>
{isAuthenticated && !showCartOption && <Cart />}
</Route>
{!isAuthenticated && <LoginForm></LoginForm>}
</Switch>
</div>
</div>
);
}
Read the documentation.
https://v5.reactrouter.com/web/guides/quick-start
This question may sound silly to some people, but I am really confused on how to do it
I have 3 file: App.js, HomePage.js and Profile.js
App.js :
import React from "react"
import { BrowserRouter as Router, Route, Switch } from "react-router-dom";
import HomePage from "./components/HomePage";
import Profile from "./components/Profile"
function App() {
return (
<Router>
<Switch>
<Route path="/" exact component={HomePage} />
<Route exact path="/profile/:profileId" component= {Profile} />
</Switch>
</Router>
);
}
export default App;
From here, the default page it will go to is HomePage.js
HomePage.js:
import React, { Component } from "react";
import axios from "axios";
import { Link } from "react-router-dom";
class HomePage extends Component {
constructor() {
super();
this.state = {
userData: [],
}
}
componentDidMount() {
axios.get("XXXXXXXX").then((response) => {
const userDataList = response.data.users;
this.setState({
userData: userDataList
})
})
}
render() {
const userGrid = this.state.userData.map((user, index) => {
return (
<div key={index}>
<Link to={`/profile/${user.id}`}>
<img src={user.profilepicture} />
<p>{user.name}</p>
</Link>
</div>
)
})
return (
<div className="App">
<div className="card">
<div className="card__top">
<span className="card__title">
<p>Select An Account</p>
</span>
</div>
<div className="card__bottom">
<div className="card__table">
{userGrid}
</div>
</div>
</div>
</div>
)
}
}
export default HomePage;
In HomePage.js, I am able to show the profile picture and name of the user from API.
In the next page which is Profile.js , I am able to print the ID of the user.
Profile.js:
import React, { Component } from "react";
class Profile extends Component{
componentDidMount(){
const uid = this.props.match.params.profileId;
}
render() {
console.log(this.props.match);
return(
<h1>{this.props.match.params.profileId}</h1>
)
}
}
export default Profile;
As you can see I am printing the ID of user.
Here I also want to show the Profile Picture of the user which I selected in HomePage.js
This I am not able to do it.
JSON file:
{ - users: [-{id:1, name:"abc", profilepicture: "xxxxx.jpeg"}, ]}
You need to store a global state in your applicattion, which you can access from every connected component. This is a more complex topic. redux is a good framework to handle your global state changes.
Here is a tutorial: https://appdividend.com/2018/06/14/how-to-connect-react-and-redux-with-example/
I found it pretty hard to learn redux, but in the end it takes away a lot of pain. Because this is a problem you gonna have in every app you build with react.
You need use Context API o redux
Example context API: https://ibaslogic.com/react-context-api/
Context's well to little projects, but Redux performs better.
App.js
import React from "react"
import { BrowserRouter as Router, Route, Switch } from "react-router-dom";
import HomePage from "./components/HomePage";
import Profile from "./components/Profile"
import { UsersProvider } from "./UsersProvider.js";
function App() {
return (
<Router>
<UsersProvider>
<Switch>
<Route path="/" exact component={HomePage} />
<Route exact path="/profile/:profileId" component= {Profile} />
</Switch>
</UsersProvider>
</Router>
);
}
export default App;
UsersContext.js
import React, { Component } from "react"
const UsersContext = React.createContext();
const UsersProvider = UsersContext.Provider;
const UsersConsumer = TodosContext.Consumer;
class MyContext extends Component {
state = {
value: null,
};
setValue = (value) => {
this.setState({ value });
};
render() {
return (
<UsersProvider value={{ setValue, value }}>{this.props.children}
</UsersProvider>
)
}
}
export { UsersContext, UsersProvider, UsersConsumer }
HomePage.js
import React, { Component } from "react";
import axios from 'axios';
class HomePage extends Component {
componentDidMount() {
axios.get("XXXXXXXX").then((response) => {
const userDataList = response.data.users;
// updating your context
this.props.context.setValue(userDataList);
})
}
render() {
const userGrid = this.props.context.value.map((user, index) => {
return (
<div key={index}>
<Link to={`/profile/${user.id}`}>
<img src={user.profilepicture} />
<p>{user.name}</p>
</Link>
</div>
)
})
return (
<div className="App">
<div className="card">
<div className="card__top">
<span className="card__title">
<p>Select An Account</p>
</span>
</div>
<div className="card__bottom">
<div className="card__table">
{userGrid}
</div>
</div>
</div>
</div>
)
}
}
export default HomePage;
Profile.js
import React, { Component } from "react";
import { UsersConsumer } from "./UsersContext.js";
class Profile extends Component{
render() {
return(
<UsersConsumer>
{users => (
<h1>{users.value.find(user => user.id === this.props.match.params.profileId)}</h1>
)}
</UsersConsumer>
)
}
}
export default Profile;
Firstly, thank you to anyone who is reading this and is willing to help!
I'm trying to build a react-redux web app, and I'm having trouble accessing an id from the url in a container. The url looks like this: websitename.com/games/:game_id
I need to access that :game_id so that I can use it in a redux action to make a call to my api, but I can't figure out how to access the usage of match. I get the following error when I try to compile:
./src/containers/GameDetails.js
Line 9:19: 'match' is not defined no-undef
My app is set up with the following structure: Main.js houses the routes:
import React from "react";
import {Switch, Route, withRouter, Redirect} from "react-router-dom";
import {connect} from "react-redux";
import Homepage from "../components/Homepage";
import AuthForm from "../components/AuthForm";
import {authUser} from "../store/actions/auth";
import {removeError} from "../store/actions/errors"
import withAuth from "../hocs/withAuth";
import GameForm from "./GameForm";
import GamePage from "../components/GamePage";
const Main = props => {
const {authUser, errors, removeError, currentUser} = props;
return (
<div className="container">
<Switch>
<Route path="/" exact render={props => <Homepage currentUser={currentUser} {...props} /> } />
<Route
path="/signin" exact
render={props => {
return(
<AuthForm
removeError={removeError}
errors={errors}
onAuth={authUser}
buttonText="Log in"
heading="Welcome Back."
{...props}
/>
)
}} />
<Route
path="/signup" exact
render={props => {
return(
<AuthForm
removeError={removeError}
errors={errors}
onAuth={authUser}
signUp
buttonText="Sign me up"
heading="Join Weekly Matchup today."
{...props}
/>
)
}}
/>
<Route
path="/games/new" exact
component={withAuth(GameForm)}
/>
<Route
path="/games/:game_id"
render={props => {
return(
<GamePage
currentUser={currentUser}
{...props}
/>
)
}}
/>
<Redirect to="/" />
</Switch>
</div>
)
}
function mapStateToProps(state){
return {
currentUser: state.currentUser,
errors: state.errors
};
}
export default withRouter(connect(mapStateToProps, {authUser, removeError})(Main));
GamePage.js is a component that has the GameDetails container in it:
import React from "react";
import { Link } from "react-router-dom";
import GameDetails from "../containers/GameDetails";
const GamePage = ({ currentUser }) => {
if (!currentUser.isAuthenticated) {
return (
<div className="home-hero">
<h1>You must sign in or sign up in order to vote for matchups and view comments.</h1>
</div>
);
}
return (
<div>
<div className="home-hero">
<GameDetails />
</div>
</div>
)
}
export default GamePage;
And GameDetails.js is where I'm trying to get the id from the url to use in my redux action:
import React, { Component } from "react";
import { connect } from "react-redux";
import { Link } from "react-router-dom";
import { getGameDetails } from "../store/actions/games";
class GameDetails extends Component {
componentDidMount() {
const game_id = match.params.game_id;
this.props.getGameDetails(game_id);
}
render() {
const { match, game } = this.props;
return (
<div className="home-hero">
<div className="offset-1 col-sm-10">
<h4>You are viewing the Game Page for game.title</h4>
</div>
</div>
);
}
}
function mapStateToProps(state) {
return {
game: state.game
};
}
export default connect(mapStateToProps, { getGameDetails })(
GameDetails
);
I'm still very new to react and redux, so I appreciate any help you can offer.
Thank you for your time and patience!
Try something like this in GameDetails.js and GamePage.js
import React from "react";
import { Link } from "react-router-dom";
import GameDetails from "../containers/GameDetails";
const GamePage = ({ currentUser, ...props }) => {
if (!currentUser.isAuthenticated) {
return (
<div className="home-hero">
<h1>You must sign in or sign up in order to vote for matchups and view comments.</h1>
</div>
);
}
return (
<div>
<div className="home-hero">
<GameDetails {...props} />
</div>
</div>
)
}
export default GamePage;
import React, { Component } from "react";
import { connect } from "react-redux";
import { Link } from "react-router-dom";
import { getGameDetails } from "../store/actions/games";
class GameDetails extends Component {
componentDidMount() {
const {game_id}= this.props.match.params.game_id;
this.props.getGameDetails(game_id);
}
render() {
const { match, game } = this.props;
return (
<div className="home-hero">
<div className="offset-1 col-sm-10">
<h4>You are viewing the Game Page for game.title</h4>
</div>
</div>
);
}
}
function mapStateToProps(state) {
return {
game: state.game
};
}
export default connect(mapStateToProps, { getGameDetails })(
GameDetails
);
I suppose you use you exported component same thing like
<Route path="/games/:game_id" component={GameDetails} />
mapStateToProps get 2 arguments state, and ownProps.
function mapStateToProps(state, ownProps) {
const { match: { params: { game_id } } } = ownProps; // you able to use game_id inside mapStateToProps
return ({ game: state.game });
}
1 solution
import React from "react";
import { Link } from "react-router-dom";
import GameDetails from "../containers/GameDetails";
const GamePage = ({ currentUser, ...routeProps }) => {
if (!currentUser.isAuthenticated) {
return (
<div className="home-hero">
<h1>You must sign in or sign up in order to vote for matchups and view comments.</h1>
</div>
);
}
return (
<div>
<div className="home-hero">
<GameDetails {...routeProps} />
</div>
</div>
)
}
export default GamePage;
2 solution
import React, { Component } from "react";
import { connect } from "react-redux";
import { Link, withRouter } from "react-router-dom";
import { getGameDetails } from "../store/actions/games";
class GameDetails extends Component {
componentDidMount() {
const game_id = match.params.game_id;
this.props.getGameDetails(game_id);
}
render() {
const { match, game } = this.props;
return (
<div className="home-hero">
<div className="offset-1 col-sm-10">
<h4>You are viewing the Game Page for game.title</h4>
</div>
</div>
);
}
}
function mapStateToProps(state) {
return {
game: state.game
};
}
export default withRouter(
connect(mapStateToProps, { getGameDetails })(GameDetails)
);
I am working with the MovieDB API. I want to show now playing movies on the root route but search result in another route.
I have tried putting history.push() method in handlesubmit but it shows error. Here's the code. Currently I am showing search result component in the home page itself.
App.js
import React, { Component } from "react";
import "./App.css";
import { BrowserRouter, Link, Switch, Route } from "react-router-dom";
import Nav from "./component/Nav";
import axios from "axios";
import { Provider } from "./context";
import Home from "./component/Home";
import SearchResult from "./component/SearchResult";
import MovieDetails from "./component/movieDetails";
class App extends Component {
state = {
movieList: [],
searchResult: [],
currentpage: 1,
totalpage: 1,
API_KEY: "c51081c224217a3989b0bc0c4b3d3fff"
};
componentDidMount() {
this.getCurrentMovies();
}
getCurrentMovies = e => {
axios
.get(
`https://api.themoviedb.org/3/movie/now_playing?api_key=${
this.state.API_KEY
}&language=en-US&page=${this.state.currentpage}`
)
.then(res => {
this.setState({
movieList: res.data.results,
currentpage: res.data.page,
totalpage: res.data.total_pages
});
console.log(this.state);
});
};
getMovies = e => {
e.preventDefault();
const moviename = e.target.elements.moviename.value;
axios
.get(
`https://api.themoviedb.org/3/search/movie?api_key=${
this.state.API_KEY
}&query=${moviename}`
)
.then(res => {
this.setState({
searchResult: res.data.results
});
console.log(this.state.searchResult);
});
console.log(this.router);
};
nextPage = () => {
this.setState(
{
currentpage: (this.state.currentpage += 1)
},
() => console.log(this.state.currentpage)
);
this.getCurrentMovies();
};
prevPage = () => {
if (this.state.movieList && this.state.currentpage !== 1) {
this.setState(
{
currentpage: (this.state.currentpage -= 1)
},
() => console.log(this.state.currentpage)
);
this.getCurrentMovies();
}
};
render() {
const contextProps = {
myState: this.state,
getMovies: this.getMovies,
nextPage: this.nextPage,
prevPage: this.prevPage,
};
return (
<Provider value={contextProps}>
<BrowserRouter>
<Nav />
<Switch>
<Route exact path="/" component={Home} />
<Route path="/:id" component={MovieDetails} />
</Switch>
</BrowserRouter>
</Provider>
);
}
}
export default App;
Home.js
import React, { Component } from "react";
import NowPlaying from "./NowPlaying";
import SearchResult from "./SearchResult";
import SearchBox from "./SearchBox";
class Home extends Component {
state = {};
render() {
return (
<div>
<SearchBox />
<SearchResult />
<NowPlaying />
</div>
);
}
}
export default Home;
SearchBox.js
import React, { Component } from "react";
import { MyContext } from "../context";
import { withRouter } from "react-router-dom";
class SearchBox extends Component {
static contextType = MyContext;
render() {
return (
<React.Fragment>
<div className="jumbotron jumbotron-fluid">
<div className="container" style={{ textAlign: "center" }}>
<h1 className="display-4">Find your Movie</h1>
<p className="lead">
Find rating, descrips and much more of your fev. movie.
</p>
<form onSubmit={this.context.getMovies}>
<input
name="moviename"
className="form-control mr-sm-2"
type="search, submit"
placeholder="Search"
aria-label="Search"
style={{ height: "50px" }}
/>
</form>
</div>
</div>
<div />
</React.Fragment>
);
}
}
export default withRouter(SearchBox);
SearchResult.js
import React, { Component } from "react";
import Movie from "./movie";
import { withRouter } from "react-router-dom";
import { MyContext } from "../context";
import SearchBox from "./SearchBox";
class SearchResult extends Component {
static contextType = MyContext;
render() {
return (
<React.Fragment>
<div className="container">
<div className="row justify-content-center">
{this.context.myState.searchResult.map(movie => {
return <Movie id={movie.id} image={movie.poster_path} />;
})}
</div>
{/* <button>Prev</button>
<button>Next</button> */}
</div>
</React.Fragment>
);
}
}
export default SearchResult;
and another thing. The pagination works for Now Playing Movies but couldn't make it to work with search result. Please help.
You can pass data with Redirect like this:
<Redirect to={{
pathname: '/movies',
state: { id: '123' }
}}
/>
and this is how you can access it:
this.props.location.state.id