简体   繁体   English

Reactjs - 向 Reducer 发送调度问题?

[英]Reactjs - Issue Sending Dispatch to Reducer?

I am working on putting together a webpage with routing and I am having trouble getting redux to work.我正在将一个带有路由的网页放在一起,但我无法让 redux 正常工作。 My goal is to send a GET response to the reducer but just to test the setup right now my goal is to send true .我的目标是向减速器发送 GET 响应,但现在只是为了测试设置,我的目标是发送true I can retrieve data from the redux store but I can't seem to send it and I am unsure where I might be going wrong.我可以从 redux 存储中检索数据,但我似乎无法发送它,而且我不确定我可能出错的地方。 Here is what is supposed to happen:这是应该发生的事情:

  1. Auth is checked in login or signup在登录或注册时检查身份验证
  2. App.js is wrapped in a provider App.js 被包装在一个提供者中
  3. User can go to Cart.js and by clicking a button dispatch the value true用户可以转到 Cart.js 并通过单击按钮发送值true
  4. The can navigate to Menu.js and should be able to console.log the new value from the reducer可以导航到 Menu.js 并且应该能够从 reducer console.log .log 新值
  5. My problem : I can't seem to actually dispatch the true value.我的问题:我似乎无法实际发送true价值。 Nothing breaks but when I go to the Menu page, the console log shows the initial state of the reducer.没有任何问题,但是当我进入菜单页面时,控制台日志显示了减速器的初始状态。
  6. This has worked for me before in React Native.这在 React Native 之前对我有用。 I'm wondering if I should be setting this up differently?我想知道我是否应该以不同的方式设置它? or if authentication is messing things up?或者如果身份验证把事情搞砸了?

Below is a sample of my code:下面是我的代码示例:

App.js应用程序.js

import React, { Component } from 'react';
import {
  Route,
  BrowserRouter as Router,
  Switch,
  Redirect,
} from "react-router-dom";
import Home from './pages/Home';
import Signup from './pages/Signup';
import Login from './pages/Login';
import Menus from './pages/Menus';
import Carts from './pages/Carts';
import Orders from './pages/Orders';
import Land from './pages/Land';
import { auth } from './services/firebase';

import { Provider } from 'react-redux';
import { createStore } from 'redux';

import ourReducer from './store/reducer';
const store = createStore(ourReducer);


global.api = 'https://pitapal.metis-data.site'
//global.api = 'http://localhost:3008';


function PrivateRoute({ component: Component, authenticated, ...rest }) {
  return (
    <Route
      {...rest}
      render={(props) => authenticated === true
        ? <Component {...props} />
        : <Redirect to={{ pathname: '/login', state: { from: props.location } }} />}
    />
  )
}

function PublicRoute({ component: Component, authenticated, ...rest }) {
  return (
    <Route
      {...rest}
      render={(props) => authenticated === false
        ? <Component {...props} />
        : <Redirect to='/home' />}
    />
  )
}

class App extends Component {

  constructor() {
    super();
    this.state = {
      authenticated: false,
      loading: true,
    };
  }

  componentDidMount() {
    auth().onAuthStateChanged((user) => {
      if (user) {
        this.setState({
          authenticated: true,
          loading: false,
        });
      } else {
        this.setState({
          authenticated: false,
          loading: false,
        });
      }
    })
  }

  render() {
    return this.state.loading === true ? <h2>Loading...</h2> : (
      <Provider store={ store }>
      <Router>
        <Switch>
          <Route exact path="/" component={Signup}></Route>
          <PrivateRoute path="/home" authenticated={this.state.authenticated} component={Home}></PrivateRoute>
          <PrivateRoute path="/menus" authenticated={this.state.authenticated} component={Menus}></PrivateRoute>
          <PrivateRoute path="/carts" authenticated={this.state.authenticated} component={Carts}></PrivateRoute>
          <PrivateRoute path="/order" authenticated={this.state.authenticated} component={Orders}></PrivateRoute>
          <PublicRoute path="/signup" authenticated={this.state.authenticated} component={Signup}></PublicRoute>
          <PublicRoute path="/login" authenticated={this.state.authenticated} component={Login}></PublicRoute>
        </Switch>

      </Router>
      </Provider>
    );
  }
}

export default App;

Reducer.js减速器.js

import { combineReducers } from 'redux';

const INITIAL_STATE = {
  carts: 'nothing'
};

const ourReducer = (state = INITIAL_STATE, action) => {
  const newState = { ...state };

  switch (action.type) {

    case "CARTS":
      return {
        ...state,
        carts: action.value
      }
      break;

  }
  return newState;
};


export default combineReducers({
  reducer: ourReducer,
});

Carts.js Carts.js

class Carts extends Component {

    render() {
            return (
            <Container>
                <Button onClick={()=>this.props.setCart(true)}>sendToRedux</Button>
            </Container>
        );
    }
}

const mapStateToProps = (state) => {
    
    const { reducer } = state
    return { reducer }
  };
  
  const mapDispachToProps = dispatch => {
    return {
      setCart: (y) => dispatch({ type: "CARTS", value: y })
    };
  }
  

  export default connect(mapStateToProps,
    mapDispachToProps
  )(Carts);

Menu.js菜单.js

 import React, { Component } from 'react';
    import Header from "../components/Header";
    import MenuItem from '../components/MenuItem';
    import classes from './menus.module.css'
    import { auth, db } from "../services/firebase";
    import { Container, Col, Row } from 'react-bootstrap';
    import { connect } from 'react-redux';
    
    class Menu extends Component {
       
    
        render() {
    
            console.log('my carts data:', this.props.reducer.carts);
           }
    
            return (
    
                <Container>
                    welcome to menu
    
                </Container>
            );
        }
    }
    
    const mapStateToProps = (state) => {
        const { reducer } = state
        return { reducer }
    };
      
    
      export default connect(mapStateToProps)(Menu);

EDIT:编辑:

here is my screenshot from Redux Devtools, this means the dispatch is definitely being sent correct?这是我在 Redux Devtools 上的截图,这意味着调度肯定是正确发送的?

So it seems the issue is that when I navigate a page using my header component, state gets reloaded, the entire app is relaoded.所以问题似乎是,当我使用我的标题组件导航一个页面时,状态被重新加载,整个应用程序被重新加载。 Wondering if someone knows what it might be.想知道是否有人知道它可能是什么。 Below is my header component:下面是我的标题组件:

Header.js头文件.js

import { Link } from 'react-router-dom';
import { auth } from '../services/firebase';
//import "./header.css";
import React, { Component } from 'react'
import { Navbar, Nav, NavItem, NavDropdown, Form, FormControl, Button } from 'react-bootstrap'
// import {Link} from 'react-router-dom'
//import classes from './navbar.module.css';
import 'bootstrap/dist/css/bootstrap.min.css';


class Header extends Component {
  render() {
    return (
      <div>

        {auth().currentUser
          ? 
            <Navbar className="fixed-top" collapseOnSelect expand="lg" style={{ backgroundColor: '#485671' }} variant="dark">
              <Navbar.Brand href="#home">PitaPal</Navbar.Brand>
              <Navbar.Toggle aria-controls="responsive-navbar-nav" />
              <Navbar.Collapse id="responsive-navbar-nav">
                <Nav className="mr-auto">

                  <Nav.Link href="/login">Home</Nav.Link>
                  <Nav.Link href="/menus">Manage my Menus</Nav.Link>
                </Nav>
                <Nav>
                <Button onClick={() => auth().signOut()} variant="outline-success">Sign Out</Button>
                </Nav>
              </Navbar.Collapse>
            </Navbar>
        
          : 
            <Navbar className="fixed-top" collapseOnSelect expand="lg" style={{ backgroundColor: '#485671' }} variant="dark">
              <Navbar.Brand href="#home">PitaPal</Navbar.Brand>
              <Navbar.Toggle aria-controls="responsive-navbar-nav" />
              <Navbar.Collapse id="responsive-navbar-nav">
                <Nav className="mr-auto">
                  <Nav.Link href="/login">Login</Nav.Link>
                  <Nav.Link href="/signup">Sign Up</Nav.Link>
                </Nav>
                <Nav>
                  <Nav.Link href="contact">Contact Us</Nav.Link>
                </Nav>
              </Navbar.Collapse>
            </Navbar>
        }





      </div>
    )
  }
}

export default Header;

在此处输入图片说明

Issue问题

Your Header is using plain anchor tags to issue navigation to your route pages which has the side-effect of also doing a page load.您的Header使用简单的锚标记向您的路线页面发出导航,这也有页面加载的副作用。

Solution解决方案

Use the react-router-dom Link component for linking.使用react-router-dom Link组件进行链接。

Either specify the as prop of the Nav.Link or use Link指定Nav.Linkas道具或使用Link

<Nav.Link as={Link} to="/login">Home</Nav.Link>

or或者

<Link to="/login">Home</Link>
class Header extends Component {
  render() {
    return (
      <div>

        {auth().currentUser
          ? 
            <Navbar className="fixed-top" collapseOnSelect expand="lg" style={{ backgroundColor: '#485671' }} variant="dark">
              <Navbar.Brand href="#home">PitaPal</Navbar.Brand>
              <Navbar.Toggle aria-controls="responsive-navbar-nav" />
              <Navbar.Collapse id="responsive-navbar-nav">
                <Nav className="mr-auto">
                  <Link to="/login">Home</Link>
                  <Link to="/menus">Manage my Menus</Link>
                </Nav>
                <Nav>
                <Button onClick={() => auth().signOut()} variant="outline-success">Sign Out</Button>
                </Nav>
              </Navbar.Collapse>
            </Navbar>
          : 
            <Navbar className="fixed-top" collapseOnSelect expand="lg" style={{ backgroundColor: '#485671' }} variant="dark">
              <Navbar.Brand href="#home">PitaPal</Navbar.Brand>
              <Navbar.Toggle aria-controls="responsive-navbar-nav" />
              <Navbar.Collapse id="responsive-navbar-nav">
                <Nav className="mr-auto">
                  <Link to="/login">Login</Link>
                  <Link to="/signup">Sign Up</Link>
                </Nav>
                <Nav>
                  <Link to="contact">Contact Us</Link>
                </Nav>
              </Navbar.Collapse>
            </Navbar>
        }
      </div>
    )
  }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM