React/Redux - mapDispatchToProps. Props undefined - reactjs

I'm looking for information in a database, in an app with react. In the actions.js file I can see the response.data data, when I put a console.table.
But even exporting, when I try to display the information, the variable's value comes as undefined.
I've already looked at the original file I'm using to learn, and I couldn't see where the error is.
action.js
import { CLEAR_SEARCH, SEARCH_CUSTOMERS } from "./actionTypes";
import Axios from "axios";
import { SEARCH_CUSTOMERS_URL } from "../../configs";
export const searchCustomers = (lat, lng, query) => dispatch => {
Axios.post(SEARCH_CUSTOMERS_URL, {
q: query,
})
.then(response => {
const customers = response.data;
console.log( "services/searchCustomers/actions.js, line 30" );
console.log( customers ); //ok, showing data
return dispatch({ type: SEARCH_CUSTOMERS, payload: customers });
})
.catch(function(error) {
console.log(error);
});
};
export const clearSearch = () => dispatch => {
const customers = [];
return dispatch({ type: CLEAR_SEARCH, payload: customers });
};
reducer.js
import { CLEAR_SEARCH, SEARCH_CUSTOMERS } from "./actionTypes";
const initialState = {
customers: []
};
export default function(state = initialState, action) {
switch (action.type) {
case SEARCH_CUSTOMERS:
return { ...state, customers: action.payload };
case CLEAR_SEARCH:
return { ...state, customers: action.payload };
default:
return state;
}
}
actionTypes.js
export const SEARCH_CUSTOMERS = "SEARCH_CUSTOMERS";
export const CLEAR_SEARCH = "CLEAR_SEARCH";
index.js
import React, { Component } from "react";
import { clearSearch, searchCustomers } from "../../../../services/searchCustomers/actions";
import Dialog from "#material-ui/core/Dialog";
import DelayLink from "../../../helpers/delayLink";
import Ink from "react-ink";
import LazyLoad from "react-lazyload";
import { Redirect } from "react-router";
import CustomerSearch from "../../CustomerSearch";
import CustomerSearchList from "../CustomerSearchList";
import { connect } from "react-redux";
import { debounce } from "../../../helpers/debounce";
import ContentLoader from "react-content-loader";
class SelectCustomer extends Component {
state = {
open: false,
queryLengthError: false,
loading: false,
showBgImage: true,
nothingFound: false,
};
handleCustomerSearch = debounce((query) => {
// call to searchCustomers search API
if (query.length >= 3) {
this.props.searchCustomers(
JSON.parse(localStorage.getItem("userSetAddress")).lat,
JSON.parse(localStorage.getItem("userSetAddress")).lng,
query
);
console.table( this.props ); //customers is undefined
this.setState({
queryLengthError: false,
loading: true,
nothingFound: false,
});
} else {
this.setState({ queryLengthError: true });
}
}, 400);
componentDidMount() {
//others
}
componentWillUnmount() {
//others
}
componentWillReceiveProps(nextProps) {
//this.props.customers is undefined
if (this.props.customers !== nextProps.customers) {
this.setState({ loading: false });
}
// console.log(nextProps.customers.length);
if (nextProps.customers) {
if (nextProps.customers.length === 0 ) {
this.setState({ showBgImage: true, nothingFound: true });
} else {
this.setState({ showBgImage: false, nothingFound: false });
}
}
//Overlay/Dialog.
if (nextProps.confirmSelectCustomerOpen === false) {
this.setState({ open: false });
}
if (nextProps.confirmSelectCustomerOpen === true) {
this.setState({ open: true });
}
}
//Overlay/Dialog
handleClose = () => {
this.setState({ open: false });
};
render() {
return (
<React.Fragment>
<Dialog
fullWidth={true}
fullScreen={false}
open={this.state.open}
onClose={this.handleClose}
style={{ width: "100%", margin: "auto" }}
PaperProps={{ style: { backgroundColor: "#fff", borderRadius: "10px" } }}
>
{this.state.queryLengthError && (
<div className="auth-error" style={{ marginBottom: "4rem" }}>
<div className="">{localStorage.getItem("searchAtleastThreeCharsMsg")}</div>
</div>
)}
<CustomerSearch searchFunction={this.handleCustomerSearch} />
{this.state.loading && (
{/*loading*/}
)}
{/* Here Should list customers */}
{this.props.customers && this.props.customers.length > 0 && (
<CustomerSearchList customers={this.props.customers} />
)}
{this.state.showBgImage && (
<div className="d-flex justify-content-center mt-100">
<img
className="img-fluid explore-bg"
src="/assets/img/various/explore-bg.png"
alt={localStorage.getItem("restaurantSearchPlaceholder")}
/>
</div>
)}
{this.state.nothingFound && (
<div className="auth-error" style={{ marginBottom: "4rem" }}>
<div className="error-shake">{localStorage.getItem("exploreNoResults")}</div>
</div>
)}
</Dialog>
</React.Fragment>
);
}
}
const mapStateToProps = (state) => ({
customers: state.customers
});
export default connect(
mapStateToProps,
{ searchCustomers, clearSearch }
)(SelectCustomer);
CustomerSearch/index.js
import React, { Component } from "react";
import Ink from "react-ink";
class CustomerSearch extends Component {
state = {
customer: ""
};
componentDidMount() {
this.searchInput.focus();
}
static contextTypes = {
router: () => null
};
handleInputChange = e => {
this.setState({ customer: e.target.value });
this.props.searchFunction(e.target.value);
};
render() {
return (
<React.Fragment>
<div className="col-12 p-0">
<div className="block m-0">
<div className="block-content p-0">
<div className="input-group search-box">
<div className="input-group-prepend">
<button
type="button"
className="btn search-navs-btns"
style={{ position: "relative" }}
onClick={this.context.router.history.goBack}
>
<i className="si si-arrow-left" />
<Ink duration="500" />
</button>
</div>
{/*
placeholder do input
{localStorage.getItem("restaurantSearchPlaceholder")}
*/}
<input
type="text"
className="form-control search-input"
placeholder="Pesquisar Cliente"
value={this.state.customer}
onChange={this.handleInputChange}
ref={input => {
this.searchInput = input;
}}
/>
<div className="input-group-append">
<button type="submit" className="btn search-navs-btns" style={{ position: "relative" }}>
<i className="si si-magnifier" />
<Ink duration="500" />
</button>
</div>
</div>
</div>
</div>
</div>
</React.Fragment>
);
}
}
export default CustomerSearch;
CustomerSearchList/index.js
import React, { Component } from "react";
import DelayLink from "../../../helpers/delayLink";
import Ink from "react-ink";
import LazyLoad from "react-lazyload";
class CustomerSearchList extends Component {
render() {
const { customers } = this.props;
return (
<React.Fragment>
{customers.map((customer) => (
<div key={customer.id} className="col-xs-12">
<DelayLink
to={"../stores/" + customer.id}
delay={200}
className="block block-link-shadow text-center light-bottom-border"
>
<Ink duration="500" />
</DelayLink>
</div>
))}
</React.Fragment>
);
}
}
export default CustomerSearchList;
reducers.js
import { combineReducers } from "redux";
....
....
import customerSearchReducer from "./searchCustomers/reducer";
import addressesReducer from "./addresses/reducer";
....
....
export default combineReducers({
...
customers: customerSearchReducer,
addresses: addressesReducer,
...
});
SEARCH_CUSTOMERS_URL - URL to php, get data:
$response = ['customers' => $customers];
Output customers: Array(3)
0: {id: 2, name: "Customer 1", email: "customer1#gmail.com"}
1: {id: 3, name: "Customer 2", email: "customer2#gmail.com"}
2: {id: 4, name: "Customer 3", email: "customer3#gmail.com"}
It's 3 days racking my brain. I did some research but I couldn't solve the problem. I'm new to react/reduce and was trying to figure it out based on this script.

As per comments... add searchCustomer reducer to rootReducer.

Related

Warning: Failed prop type: The prop `id` is marked as required in `User`, but its value is `undefined`

/* 0.chunk.js:33320 Warning: Failed prop type: The prop id is marked as required in User, but its value is undefined.
at User (http://localhost:3000/static/js/main.chunk.js:231:5)
at Users (http://localhost:3000/static/js/main.chunk.js:384:1)
at div
at App (http://localhost:3000/static/js/main.chunk.js:109:1)
at UserProvider (http://localhost:3000/static/js/main.chunk.js:460:5)*/
import React, { Component } from "react";
import PropTypes from "prop-types";
import UserConsumer from "../context";
class User extends Component {
state = {
isVisible: false,
};
//Destructing
static defaultProps = {
name: "bilgi yok",
salary: "bilgi yok",
department: "bilgi yok",
};
onClickEvent = (e) => {
this.setState({
isVisible: !this.state.isVisible,
});
};
onDeleteUser = (dispatch, e) => {
const {id} = this.props;
//Consumer Dispatch
dispatch({ type: "DELETE_USER", payload: id });
};
render() {
const { name, department, salary } = this.props;
const { isVisible } = this.state;
return (
<UserConsumer>
{(value) => {
const { dispatch } = value;
return (
<div className="col-md-8 mb-4">
<div className="card">
<div className="card-header d-flex justify-content-between">
<h4 className="d-inline" onClick={this.onClickEvent}>
{name}
</h4>
<i
onClick={this.onDeleteUser.bind(this, dispatch)}
className="far fa-trash-alt"
style={{ cursor: "pointer" }}
></i>
</div>
{isVisible ? (
<div className="card-body">
<p className="card-text">Maas : {salary}</p>
<p className="card-text">Department : {department}</p>
</div>
) : null}
</div>
</div>
);
}}
</UserConsumer>
);
}
}
User.propTypes = {
name: PropTypes.string.isRequired,
salary: PropTypes.string.isRequired,
department: PropTypes.string.isRequired,
id: PropTypes.number.isRequired,
};
User.defaultProps = {};
export default User; /* Başka classlarda kullanılmak için export edildi*/
import React, { Component } from "react";
import User from "./User";
import UserConsumer from "../context";
class Users extends Component {
render() {
return (
<UserConsumer>
{(value) => {
const { users } = value;
return (
<div>
{users.map((user) => {
return (
<User
key={user.id}
name={user.name}
salary={user.salary}
department={user.department}
/>
);
})}
</div>
);
}}
</UserConsumer>
);
}
}
export default Users;
//This is where is used

React: Sorting and filter product by price and size using react redux

I want to filter product by size and also sort it by size but when I implement it in redux I get the error that map its not a function in product component here is my action Creator page. This is where I fetch the product from server
export const fetchProduct = () => (dispatch) => {
dispatch(productLoading(true));
return fetch(baseUrl + "products")
.then(
(response) => {
console.log('response',response)
if (response.ok) {
return response;
} else {
var error = new Error(
"Error " + response.status + ": " + response.statusText
);
error.response = response;
throw error;
}
},
(error) => {
var errmess = new Error(error.message);
throw errmess;
}
)
.then((response) => response.json())
.then((products) => dispatch(addProduct(products)))
.catch((error) => dispatch(productFailed(error.message)));
};
export const productLoading = () => ({
type: ActionTypes.PRODUCT_LOADINGS,
});
export const productFailed = (errmess) => ({
type: ActionTypes.PRODUCT_FAILURES,
payload: errmess,
});
export const addProduct = (products) => ({
type: ActionTypes.ADD_PRODUCTS,
payload: products,
});
export const filterProducts = (product, size) => (dispatch) => {
dispatch({
type: ActionTypes.FILTER_PRODUCTS_BY_SIZE,
payload: {
size: size,
products:
size === ""
? product
: product.filter((x) => x.availableSizes.indexOf(size) >= 0),
},
});
};
Here is where I short and filter the product
export const sortProducts = (sort, filteredProduct) => (dispatch) => {
const sortedProduct = filteredProduct.slice();
if (sort === "latest") {
sortedProduct.sort((a, b) => (a._id > b._id ? 1 : -1));
} else {
sortedProduct.sort((a, b) =>
sort === "lowest"
? a.price > b.price
? 1
: -1
: a.price > b.price
? -1
: 1
);
}
dispatch({
type: ActionTypes.SORT_PRODUCT_BY_PRICE,
payload: { sort: sort, products: sortedProduct },
});
};
This is my productReducer.js page
import * as ActionTypes from "./ActionsType";
export const productsReducer = (
state = {
isLoading: true,
errMess: null,
products: [],
},
action
) => {
switch (action.type) {
case ActionTypes.FILTER_PRODUCTS_BY_SIZE:
return {
...state,
size: action.payload.size,
filteredItems: action.payload.products,
};
case ActionTypes.SORT_PRODUCT_BY_PRICE:
return {
...state,
sort: action.payload.sort,
filteredItems: action.payload.products,
};
case ActionTypes.ADD_PRODUCTS:
console.log(" products: action.payload, filteredItems:action.payload", {
products: action.payload,
filteredItems: action.payload,
});
return {
...state,
isLoading: false,
errMess: null,
products: action.payload,
filteredItems: action.payload,
};
case ActionTypes.PRODUCT_LOADINGS:
return { ...state, isLoading: true, errMess: null, products: [] };
case ActionTypes.PRODUCT_FAILURES:
return {
...state,
isLoading: false,
errMess: action.payload,
products: [],
};
default:
return state;
}
};
This is my main component where I passed the product as props to product component
import React, { Component } from "react";
import Footer from "./FooterComponent";
import { Header } from "./HeaderComponent";
import Product from "./ProductsComponent";
import { Switch, Route, Redirect, withRouter } from "react-router-dom";
import { Sidebar } from "./Sidebars";
import {
addProductToCart,
addToCart,
decrementCartQuantity,
fetchProduct,
filterProducts,
incrementCartQuantity,
loginUser,
removeFromCart,
SignUpReq,
sortProducts,
} from "../redux/ActionCreators";
import { connect } from "react-redux";
import ProductDetailsComponent from "./ProductDetailsComponent";
import SignupForm from "./signup";
import AboutUs from "./AboutUs";
import { actions } from "react-redux-form";
import Signup from "./Signup copy 2";
import CartItemsComponent from "./CartItemsComponent";
import Filter from "./Filter";
const mapStateToProps = (state) => {
return {
products: state.product.filteredItems,
product: state.product.products,
size: state.product.size,
sort: state.product.sort,
filteredProducts: state.product.filteredItems,
};
};
const mapDispatchToProps = (dispatch) => ({
fetchProduct: () => dispatch(fetchProduct()),
filterProducts: () => dispatch(filterProducts()),
sortProducts: () => dispatch(sortProducts()),
},
});
class Main extends Component {
componentDidMount() {
this.props.fetchProduct();
}
render() {
const GetItem = ({ match, params }) => {
return (
<ProductDetailsComponent
product={
this.props.products.filter(
(product) => product._id === match.params.productId
)[0]
}
isLoading={this.props.products.isLoading}
errMess={this.props.products.errMess}
addToCart={this.props.addToCart}
/>
);
};
return (
<div>
<Header
loginUser={this.props.loginUser}
cartItems={this.props.cartItems}
/>
<Filter
filterProducts={this.props.filterProducts}
sortProducts={this.props.sortProducts}
product={this.props.products}
filteredProducts={this.props.filteredProducts}
/>
<Switch>
<Route
exact
path="/"
component={() => (
<Product
product={this.props.products}
/>
)}
/>
<Route path="/:productId" component={GetItem} />
<Route exact path="/contactus" />
<Redirect to="/default" />
</Switch>
<Footer />
</div>
);
}
}
export default withRouter(connect(mapStateToProps, mapDispatchToProps)(Main));
This is my ProductsComponent.js page
import React from "react";
import { Loading } from "./LoadingComponent";
import { GridWrapper } from "./StyleComponent";
import {
Card,
CardImg,
CardTitle,
Button,
Breadcrumb,
BreadcrumbItem,
} from "reactstrap";
import { Link } from "react-router-dom";
import { baseUrl } from "./shared/baseUrl";
import formatCurrency from "./shared/util";
function RenderProductItem({ product, addToCart }) {
return (
<div className="container">
<div className="card">
<Link to={`/${product._id}`}>
<div className="img-container p-5">
<img
src={baseUrl + product.image}
alt={product.title}
className="card-img-top"
/>
</div>
</Link>
<div className="d-flex justify-content-between">
<p className="align-self-center mb-0">{product.title}</p>
<h5 className="text-blue align-self-center font-italic mb-0">
<span className="mr-1">{formatCurrency(product.price)}</span>
</h5>
</div>
<div className="card-footer ">
<button
className="buttonContainer col-12"
onClick={() => {
addToCart(product);
}}
>
add-to-cart
</button>
</div>
</div>
</div>
);
}
function Product(props) {
console.log( "props", props)
const products = props.product.map((product) => {
return (
<div key={product._id} className="col-12 mx-auto col-md-5 my-3">
<RenderProductItem product={product} addToCart={props.addToCart} />
</div>
);
});
if (props.product.isLoading) {
return (
<div className="container">
<div className="row">
<Loading />
</div>
</div>
);
}
else if (props.product.errMess) {
return (
<div className="container">
<div className="row">
<h4>{props.product.errMess}</h4>
</div>
</div>
);
} else
return (
<>
<div className="container">
<div className="row">
<Breadcrumb>
<BreadcrumbItem>
<Link to="/home">Home</Link>
</BreadcrumbItem>
<BreadcrumbItem active>Products</BreadcrumbItem>
</Breadcrumb>
<div className="col-12">
<h3>Products</h3>
<hr />
</div>
</div>
<div className="row">{products}</div>
</div>
</>
);
}
export default Product;
This is my filter.js page
import React, { Component } from "react";
class Filter extends Component {
render() {
return !this.props.filteredProducts ? (
<div>Loading...</div>
) : (
<div className="filter">
<div className="filter-result">
{this.props.filteredProducts.length} Products
</div>
<div className="filter-sort">
Order{" "}
<select
value={this.props.sort}
onChange={(e) =>
this.props.sortProducts(
this.props.filteredProducts,
e.target.value
)
}
>
<option value="latest">Latest</option>
<option value="lowest">Lowest</option>
<option value="highest">Highest</option>
</select>
</div>
<div className="filter-size">
Filter{" "}
<select
value={this.props.size}
onChange={(e) =>
this.props.filterProducts(this.props.product, e.target.value)
}
>
<option value="">ALL</option>
<option value="XS">XS</option>
<option value="S">S</option>
<option value="M">M</option>
<option value="L">L</option>
<option value="XL">XL</option>
<option value="XXL">XXL</option>
</select>
</div>
</div>
);
}
}
export default Filter

How to redirect to a another page in reactjs when switch case statement is executed?

I want to know how to make a redirection after a case statement. I have been making this code, but after the case statement, nothing happens. I review on the web, but nothing seems to work.When i submit the validated form, it doesn't redirect or refreshes.
Code
import { Redirect } from 'react-router-dom'
import React, { Component } from 'react'
const initState = {}
const adReducer = (state = initState, action) => {
switch (action.type) {
case 'CREATE_AD_SUCCESS':
alert('create ad success');
return <Redirect to='/' /> ;
case 'CREATE_AD_ERROR':
alert('create ad error');
return state;
default:
return state;
}
};
export default adReducer;
adAction.js code
export const createAd = (ad) => {
return (dispatch, getState, {getFirebase,getFirestore}) => {
// make async call to database
const firestore = getFirestore();
const profile = getState().firebase.profile;
const authorId = getState().firebase.auth.uid;
firestore.collection('ads').add({
...ad,
authorFirstName: profile.firstName,
authorLastName: profile.lastName,
authorId: authorId,
createdAt: new Date()
}).then(() => {
dispatch({ type: 'CREATE_AD_SUCCESS' });
}).catch(err => {
dispatch({ type: 'CREATE_AD_ERROR' }, err);
});
}
};
Create ad code :
import React, { Component } from 'react'
import { connect } from 'react-redux'
import { createAd } from '../../store/actions/adActions'
import { Redirect } from 'react-router-dom'
import firebase from "firebase";
import FileUploader from "react-firebase-file-uploader";
class CreateAd extends Component {
state = {
title: '',
content: '',
avatar: "",
isUploading: false,
progress: 0,
avatarURL: "",
contactno:""
}
handleChange = (e) => {
this.setState({
[e.target.id]: e.target.value
})
}
handleSubmit = (e) => {
e.preventDefault();
this.props.createAd(this.state);
}
handleUploadStart = () => this.setState({ isUploading: true, progress: 0 });
handleProgress = progress => this.setState({ progress });
handleUploadError = error => {
this.setState({ isUploading: false });
console.error(error);
};
handleUploadSuccess = filename => {
this.setState({ avatar: filename, progress: 100, isUploading: false });
firebase
.storage()
.ref("images")
.child(filename)
.getDownloadURL()
.then(url => this.setState({ avatarURL: url }));
};
render() {
const { auth } = this.props;
if (!auth.uid) return <Redirect to='/signin' />
return (
<div className="container">
<form className="white" onSubmit={this.handleSubmit}>
<h5 className="grey-text text-darken-3">Create a New Ad</h5>
<div className="input-field">
<input type="text" id='title' onChange={this.handleChange} />
<label htmlFor="title">Ad Title</label>
</div>
<div className="input-field">
<textarea id="content" className="materialize-textarea" onChange={this.handleChange}></textarea>
<label htmlFor="content">AdContent</label>
</div>
<div className="input-field">
<input type="text" id='contactno' onChange={this.handleChange} />
<label htmlFor="title">Contact Number</label>
</div>
{ this.state.progress==100? <div class="col-md-4">
<img class="responsive-img" src={this.state.avatarURL}></img>
</div>:""}
<br/>
<label style={{backgroundColor: 'steelblue', color: 'white', padding: 10, borderRadius: 4, pointer: 'cursor'}}>
Upload a photo
{/* {this.state.isUploading && <p>Progress: {this.state.progress}</p>}
{this.state.avatarURL && <img src={this.state.avatarURL} />} */}
<FileUploader
hidden
accept="image/*"
storageRef={firebase.storage().ref('images')}
onUploadStart={this.handleUploadStart}
onUploadError={this.handleUploadError}
onUploadSuccess={this.handleUploadSuccess}
onProgress={this.handleProgress}
/>
</label>
<div className="input-field">
<button className="btn pink lighten-1">Create</button>
</div>
</form>
</div>
)
}
}
const mapStateToProps = (state) => {
return {
auth: state.firebase.auth
}
}
const mapDispatchToProps = dispatch => {
return {
createAd: (ad) => dispatch(createAd(ad))
}
}
export default connect(mapStateToProps, mapDispatchToProps)(CreateAd)
These are my codes.
You should use return window.location.replace("/") instead of return <Redirect to="/" />.
"React Router Redirect" redirects from A to B, for example <Redirect from="/about" to="/" />

React Router/Context API Search Component

I used to make this code work out for my search component but after the on submit is called, I receive this error which never happened before, does anyone have any clue???
Maximum update depth exceeded. This can happen when a component repeatedly calls setState inside componentWillUpdate or componentDidUpdate. React limits the number of nested updates to prevent infinite loops.
import React, { Component } from "react";
import axios from "axios";
import { Redirect } from "react-router-dom";
import { Consumer } from "../context";
class Search extends Component {
constructor() {
super();
this.state = {
productTitle: "",
apiUrl: "*******************************",
redirect: false
};
}
findProduct = (dispatch, e) => {
e.preventDefault();
axios
.post(
`${this.state.apiUrl}`,
JSON.stringify({ query: this.state.productTitle })
)
.then(res => {
dispatch({
type: "SEARCH_TRACKS",
payload: res.data.output.items
});
this.setState({ items: res.data.output.items, redirect: true });
})
.catch(err => console.log(err));
};
onChange = e => {
this.setState({ [e.target.name]: e.target.value });
};
render() {
const { redirect } = this.state;
if (redirect) {
return <Redirect to="/searchresult" />;
}
return (
<Consumer>
{value => {
const { dispatch } = value;
return (
<div>
<form onSubmit={this.findProduct.bind(this, dispatch)}>
<div className="form-group" id="form_div">
<input
type="text"
className="form-control form-control-md"
placeholder="...محصولات دسته یا برند مورد نظرتان را انتخاب کنید"
name="productTitle"
value={this.state.productTitle}
onChange={this.onChange}
/>
<button className="btn" type="submit">
<i className="fas fa-search" />
</button>
</div>
</form>
</div>
);
}}
</Consumer>
);
}
}
import React, { Component } from 'react'
import axios from 'axios'
const Context = React.createContext();
export const axiosDashboard = () => {
const URL = (`*****************`);
return axios(URL, {
method: 'POST',
data: JSON.stringify({refresh:"true"}),
})
.then(response => response.data)
.catch(error => {
throw error;
});
};
const reducer = (state, action) => {
switch(action.type){
case 'SEARCH_TRACKS':
return {
...state,
items: action.payload,
heading: 'Search Results'
};
default:
return state;
}
}
export class Provider extends Component {
state = {
dispatch:action => this.setState(state => reducer(state, action))
}
render() {
return (
<Context.Provider value={this.state}>
{this.props.children}
</Context.Provider>
)
}
}
export const Consumer = Context.Consumer
import React, { Component } from 'react'
import { Consumer } from '../context'
import SearchResult from './SearchResult'
import './Search.css'
class Tracks extends Component {
render() {
return (
<Consumer>
{value => {
const { items } = value
if(items === undefined || items.length === 0){
return 'hello'}
else{
return(
<React.Fragment>
<div id='products_search'>
<div className='container'>
<div className="row justify-content-end">
{items.map(item => (
<SearchResult
key={item.id}
id={item.id}
title={item.name}
current_price={item.current_price}
lowest_price={item.lowest_price}
store_name={item.store_name}
thumb={item.thumb_url}/>
))}
</div>
</div>
</div>
</React.Fragment>
)
}
}}
</Consumer>
)
}
}
export default Tracks
import React from 'react'
import {Link} from 'react-router-dom'
import './Search.css'
const SearchResult = (props) => {
const {title,current_price,lowest_price,thumb,id,store_name} = props
return (
<div className="col-md-3" id="searchresult">
<img src={thumb} alt=""/>
<div className="sexy_line"></div>
<p className="muted">{store_name}</p>
<h6>{title}</h6>
<p>{lowest_price}</p>
<Link to={`products/item/${id}`}>
<button type="button" className="btn btn-light rounded-pill">{
new Intl
.NumberFormat({style: 'currency', currency: 'IRR'})
.format(current_price)
}</button>
</Link>
</div>
)
}
export default SearchResult
Maximum update depth exceeded.
This means that you are in a infinit loop of re rendering a component.
The only place where I can see this is possible to happen is in this part
if (redirect) {
return <Redirect to="/searchresult" />;
}
Maybe you are redirecing to the a route that will get the same component that have the redirect.
Please check if you aren't redirecting to the same route as this component and provide your routes and what is inside Consumer.

how to pass props from parent to child component

I have a list of comments on soccer champions, and am trying to display comments of each soccer champion separately. I'm trying to order by id in firebase, but don't know how I can pass id from the champion component to the component where I display all the comments. It's just giving me undefined for some reason. Any help is greatly appreciated!
champ.js
import React, { Component } from "react";
import { ChampsRef, timeRef } from "./reference";
import { getsinglechamp } from "../actions/champs";
import { connect } from "react-redux"; // this is not being used. oh isee so like this?
import { Redirect, Link } from "react-router-dom";
import { Container, Row, Col } from "reactstrap";
import { Upvote } from "react-upvote";
import Form from "./Form";
import { Icon } from "react-icons-kit";
import Specials from "./specials";
import app from "../config/dev";
import { chevronDown } from "react-icons-kit/fa/chevronDown";
import { chevronUp } from "react-icons-kit/fa/chevronUp";
class OneChamp extends Component {
state = {
name: "",
weak: [],
img: "",
authenticated: false,
currentUser: null,
email: ""
};
componentDidMount() {
app.auth().onAuthStateChanged(user => {
if (user) {
this.setState({
currentUser: user,
email: user.email,
authenticated: true
});
} else {
this.setState({
currentUser: null,
authenticated: false
});
}
});
}
componentWillMount() {
const { dispatch, match } = this.props;
dispatch(getsinglechamp(match.params.id));
console.log(this.props);
}
render() {
console.log(this.props.champ);
const { dispatch, loading } = this.props;
const authenticated = this.state.authenticated;
console.log("change", this.props);
console.log("c", this.props.champ.img);
console.log("", this.props.champ.stats);
const champ = this.props.champ.stats;
let content = null;
if (loading) {
content = <p>Loading...</p>;
} else {
content = (
<div id="f">
<div className="ChampionHeader_row_ArTlM">
<div
style={{
paddingRight: "0.75rem",
paddingLeft: "0.75rem",
flexGrow: 1
}}
>
<div style={{ display: "flex", marginBottom: "1.5rem" }}>
<div style={{ flexShrink: 0, marginRight: "1rem" }}>
<div className="IconChampion_component_2qg6y IconChampion_lg_2QLBf">
<img
className="v-lazy-image v-lazy-image-loaded IconChampion_img_3U2qE"
src={this.props.champ.img}
height="80px"
/>
</div>
</div>
</div>
</div>
</div>
<div className="timeline-panel">
<div className="timeline-heading">
{" "}
<h4>{this.props.champ.name}</h4>
</div>
<ul>
{Object.keys(champ).map((item, i) => (
<div className="card">
<li className="travelcompany-input" key={i}>
<div> {champ[item]}</div>
</li>
</div>
))}
</ul>
<br />
<div className="w3-container">
// place i want to pass id <Comments id={this.props.champ.id} />
<h2>Weak To</h2> <br />
<ul className="w3-ul w3-card-4">
<li className="w3-bar">
<img
src={this.props.champ.img2}
className="w3-bar-item w3-circle w3-hide-small"
style={{ width: 145 }}
/>
<div className="w3-bar-item">
<span className="w3-large">{this.props.champ.weak}</span>
<br />
<span id="item"> Mid </span>
<div className="col-sm-5">
<span className="label label-primary">
{this.props.champ.win}
</span>
</div>
</div>
</li>
<li className="w3-bar">
<img
src={this.props.champ.img3}
className="w3-bar-item w3-circle w3-hide-small"
style={{ width: 145 }}
/>
<div className="w3-bar-item">
<Link to={`/Matchup/${this.props.champ.id}`}>
{" "}
<span className="w3-large">{this.props.champ.weak3}</span>
<br />{" "}
</Link>
<span id="item"> Mid </span>
<span className="label label-primary">
{this.props.champ.win}
</span>
</div>
</li>
</ul>
</div>
</div>
<div />
{authenticated ? (
<div className="nav-item">
<Form id={this.props.champ.id} />
</div>
) : (
<div className="nav-item">
    
<Link to="/login" className="nav-link2">
{" "}
Login to post
</Link>
</div>
)}
</div>
);
}
return <div>{content}</div>;
}
}
const mapStateToProps = state => {
console.log("champs", state.champs);
console.log(state.loading);
return {
champ: state.champs.champ,
loading: state.loading
};
};
export default connect(
mapStateToProps,
null
)(OneChamp);
comments.js
import React, { Component } from "react";
import axios from "axios";
import app from "../config/dev";
import { Link } from "react-router-dom";
import { ChampsRef, CommentsRef, timeRef } from "./reference";
import { connect } from "react-redux";
import { getsinglechamp } from "../actions/champs";
class Comments extends Component {
state = {
comments: [],
champ_id: "",
loading: true,
email: ""
};
componentWillMount() {
const champ_id = this.props.champ.id;
console.log("id", this.props.champ);
CommentsRef.orderByChild("champ_id")
.equalTo(`${champ_id}`)
.on("value", snap => {
const tasks = [];
let comments = [];
snap.forEach(child => {
comments.push({ ...child.val(), key: child.key });
});
this.setState({ comments: comments, Loading: false });
});
}
render() {
const { dispatch, loading } = this.props;
const { comments, ChampsLoading } = this.state;
const orderedchamps = comments;
let commentList;
if (ChampsLoading) {
commentList = <div className="TaskList-empty">Loading...</div>;
} else if (comments.length) {
commentList = (
<ul className="TaskList">
{comments.map(comment => (
<div>{comment.text}</div>
))}
</ul>
);
}
return (
<div>
<h1> Popular Cham</h1>
<p> {commentList} </p>
</div>
);
}
}
const mapStateToProps = state => {
console.log("champs", state.champs);
console.log(state.loading);
return {
champ: state.champs.champ,
loading: state.loading
};
};
export default connect(
mapStateToProps,
null
)(Comments);

Resources