0

I have a navbar for all pages. I want to make a cart in it, however, when I go to the internal product page, the props that I transmit are not displayed. enter image description here enter image description here

Why is this happening ? I think this is my problem React router v4 not working with Redux but how i can implement this ? What do you think ?

App.js

   import React, {Component} from 'react';
import {Container} from 'reactstrap';
import {
  BrowserRouter,
  Route,
  Switch
} from "react-router-dom";

import './App.css';
import NavbarMenu from './components/navbar'
import Main from './components/main';
import Good from './components/good';

class App extends Component {

  render() {
    return (
      <BrowserRouter>
        <div className="App">
          <NavbarMenu/>
          <Container>
            <Switch>
              <Route path="/" exact component={Main}/>
              <Route path="/good/:id" component={Good}/>
            </Switch>
          </Container>
        </div>
      </BrowserRouter>
    );
  }
}

export default App;

navbar

  import React from 'react';
import {
  Collapse,
  Navbar,
  NavbarToggler,
  NavbarBrand,
  Nav,
  UncontrolledDropdown,
  DropdownToggle,
  DropdownMenu,
  DropdownItem,
  Button
} from 'reactstrap';
import {withRouter} from 'react-router-dom';
import connect from 'react-redux/es/connect/connect';
import {getCart} from '../../redux/actions/cartAction';

class NavbarMenu extends React.Component {
  constructor(props) {
    super(props);

    this.toggle = this.toggle.bind(this);
    this.state = {
      isOpen: false
    };
  }

  toggle() {
    this.setState({
      isOpen: !this.state.isOpen
    });
  }

  render() {
console.log(this.props)
    const cartLength = this.props.cart.length;
    const cartItems = this.props.cart.map(e => {
      return <div key={e.id} style={{marginBottom: '20px'}}>
        <DropdownItem
          style={{display: 'inline-block', width: 'auto'}}
          onClick={() => {
            this.props.history.push('/good/' + e.id)
          }}>
          {e.name}
        </DropdownItem>
        <Button
          style={{display: 'inline-block', float: 'right', marginRight: '20px'}}
          color="danger"
        >X</Button>
      </div>
    });

    return (
      <Navbar
        color="light"
        light expand="md"
        style={{marginBottom: '20px'}}
      >
        <NavbarBrand
          style={{cursor: 'pointer'}}
          onClick={() => {
            this.props.history.push('/')
          }}
        >
          Shop
        </NavbarBrand>
        <NavbarToggler onClick={this.toggle}/>
        <Collapse isOpen={this.state.isOpen} navbar>
          <Nav className="ml-auto" navbar>
            <UncontrolledDropdown nav inNavbar>
              <DropdownToggle nav caret>
                Cart: {cartLength} items
              </DropdownToggle>
              <DropdownMenu right style={{width: '300px'}}>
                {cartItems}

                <DropdownItem divider/>

              </DropdownMenu>
            </UncontrolledDropdown>
          </Nav>
        </Collapse>
      </Navbar>
    );
  }
}

const mapStateToProps = state => ({
  cart: state.cart.cart
});

export default withRouter(connect(mapStateToProps, {getCart})(NavbarMenu));
Стас Рябцев
  • 1,318
  • 4
  • 19
  • 36

2 Answers2

0

Based on the prints you gave, you are opening the item on a diferent window, because of that, the variables on the session in the window are not passed.

One solution you could use is to save pieces of your store that you will need later in the browser localStorage.

You can do that using this by using the Redux subscribe function.

A example could be:

localStorage.js

export const loadState = () => {
  try {
    const serializedState = localStorage.getItem('state');
    if (serializedState === null) return undefined;

    return JSON.parse(serializedState);
  } catch (err) { return undefined; }
};

export const saveState = (state) => {
  try {
    const serializedState = JSON.stringify(state);
  } catch (err) {
    // errors
  }
}

And in the redux store you can put:

import { loadState, saveState } from './localStorage'; 

const persistedState = loadState();
const store = createStore(persistedState);

store.subscribe(() => saveState(store.getState()));

Source: https://egghead.io/lessons/javascript-redux-persisting-the-state-to-the-local-storage

  • I get data from the database using Redux and I do not need to store it in localstorage http://joxi.ru/KAg8KE1uEKwqlr . I need to get it from database – Стас Рябцев Feb 12 '19 at 19:01
  • @СтасРябцев try putting const mapStateToProps = state => ({ cart: state.cart }); instead of state.cart.cart – Pedro Paulo Feb 12 '19 at 19:08
  • I wasn't understanding why it was cart.cart and though that could be the problem. But try now saving the store and loading from the localStorage. The problem is that when you open a new window, new variables are loaded, so, a new store is loaded. If you load the store from the localStorage, it will be with the data needed. If you see the logs, the first console.log on the main page displays the cart with 0 itens, then something occurs to put an item on the cart, so, if you save this data on the localStorage, you could load the data in a new window and load the app with the data that you want. – Pedro Paulo Feb 12 '19 at 19:29
  • No it's because I have object and array cart http://joxi.ru/Dr86KoQSoMeay2 the problem is something else, I think it is somehow related to the routing – Стас Рябцев Feb 12 '19 at 19:33
  • If you open the item on the same window that you are, instead of opening a new one, the cart will be with the values that you want? (sorry for the late answer, btw) – Pedro Paulo Feb 13 '19 at 03:09
0

I solved my problem by adding this code

componentDidMount() {
   this.props.getCart();
}
Стас Рябцев
  • 1,318
  • 4
  • 19
  • 36