subscription()不起作用,不能getState()

时间:2019-09-08 13:43:24

标签: reactjs redux redux-store

我想订阅状态更改并在需要时重新渲染组件(状态更改) 呈现2个组件。我从中进行更新的一项(产品列表)和我从中显示所选项目的更新列表(产品购物车)

我无法从购物车中获取状态

这是购物车组件-我要在其中订阅商店c并在状态更改时重新呈现(不起作用)

import React, { Component } from 'react';
import Card from './Card'
import { connect } from "react-redux";
import { Link } from "react-router-dom";
import store from '../lib/reducers/index'

const mapStateToProps = state => {
    return { bookings: state.bookings };
};

class CartDetails extends Component {
    constructor(props) {
        super(props)
        this.style = {
            height: "50px",
            margin: "5px 0", 
            borderRadius: "0"
        }

        // store.subscribe(() => {
        //     console.log(store.getState())
        //     this.setState({
        //         bookings: store.getState()
        //     });
        // });
    } 


    render() {
        const bookings = this.props.bookings
        return (<div className="side">
        <ul className="list-group list-group-flush">
            {bookings.map(booking => {
                console.log("details " + booking.hotelDetails.bg)

                return(<Card key={booking.id} bg={booking.hotelDetails.bg} style={this.style}> 
                            <ul className="ml-auto mx-auto price text-right">
                                <li>€{booking.hotelDetails.price}</li>
                                <li>prix/nuit</li>
                            </ul>
                      </Card>)
            })}
        </ul>
        <button className="btn btn-light float-right"><Link to="/order">Recap</Link></button>
    </div>)
    }
}

const Cart = connect(mapStateToProps)(CartDetails);
export default Cart;

这是HotelDetails组件-我在其中选择日期,夜晚以预订夜晚

import React, { Component } from 'react';
import bgImg from '../resources/1445991842772-097fea258e7b.jpeg'
import DatePicker from "react-datepicker";
import Card from './Card'
import "react-datepicker/dist/react-datepicker.css";
import { connect } from "react-redux";
import { addBooking } from "../lib/actions/index";
import PropTypes from 'prop-types'

function mapDispatchToProps(dispatch) {
    return {
        addBooking: payload => dispatch(addBooking(payload))
    };
}

class FormReservation extends Component {
    constructor(props) {
        super(props)
        this.state = {
            hotelDetails: {},
            nights: 1,
            rooms: 0,
            startDate: new Date(),
            endDate: new Date(),
            price: 0,
            details: ""
        }
        this.hotels = [
            { bg: '1445991842772-097fea258e7b', price: 400 },
            { bg: '1496417263034-38ec4f0b665a', price: 300 },
            { bg: '1444201983204-c43cbd584d93', price: 450 },
            { bg: '1486591038957-19e7c73bdc41', price: 280 },
            { bg: '1515362655824-9a74989f318e', price: 320 },
            { bg: '1518733057094-95b53143d2a7', price: 550 },
            { bg: '1519449556851-5720b33024e7', price: 400 },
            { bg: '1525905708812-b271b5e3b2f3', price: 180 },
            { bg: '1495754149474-e54c07932677', price: 300 },
            { bg: '1561578428-b13076fe7ea0', price: 200 },
            { bg: '1566399468396-07a2a14911a6', price: 400 },
            { bg: '1544305776-64b90477a4da', price: 500 },
            { bg: '1487757619811-5dad58c96a7a', price: 400 },
            { bg: '1421790735934-58176b8292a7', price: 600 },
            { bg: '1551043415-844a4ab9f4fa', price: 450 }
        ]

        this.style = {
            height: "150px",
            margin: "10px",
            borderRadius: "0"
        }
    }

    componentDidMount() {
        this.setCheckout()
        const id = this.props.match.params.id
        let hotel = this.hotels.filter(hotel => {
            return hotel.bg == id
        })
        console.log('hotel ' + hotel)
        this.setState({ hotelDetails: hotel })
    }

    setCheckout = () => {
        let day = this.state.startDate.getDate() + parseInt(this.state.nights)
        let month = this.state.startDate.getMonth() + 1
        let year = this.state.startDate.getFullYear()
        this.setState({
            endDate: new Date(month + "/" + day + "/" + year)
        })
    }

    setNights = () => {
        const second = 1000, minute = second * 60, hour = minute * 60, day = hour * 24
        const distance = Math.floor((this.state.endDate.getTime() - this.state.startDate.getTime()) / day)
        this.setState({ nights: distance })
    }
    onAdd = e => {
        e.preventDefault()
        const { startDate, endDate, nights, rooms, hotelDetails } = this.state;
        if (nights == 0 || rooms == 0) { return false }
        let id = new Date().getTime();
        this.props.addBooking({ id, startDate, endDate, nights, rooms, hotelDetails });
    }

    onNightsSelect = e => {
        this.setState({ nights: e.target.value }, () => {
            this.setCheckout()
        })
    }

    onRoomSelect = e => {
        this.setState({ rooms: e.target.value })
    }

    handleCheckIn = e => {
        this.setState({ startDate: e }, () => { this.setCheckout() })
    }

    handleCheckOut = e => {
        this.setState({ endDate: e }, () => { this.setNights() })
    }

    render() {
        const id = this.props.match.params.id
        return (
            <div>
                <Card bg={id} style={this.style}></Card>
                <div id="hotelDetails">

                    <div className="bgImg"
                        style={{
                            backgroundImage: `url('${bgImg}')`,
                            backgroundSize: 'cover'
                        }}></div>

                    <br /> <br />
                    <div className="container">

                        <div className="row">
                            <div className="col-md-6">
                                <DatePicker
                                    className="form-control datepicker"
                                    selected={this.state.startDate}
                                    onChange={(e) => this.handleCheckIn(e)}
                                    dateFormat="EEEE, MMM d, yyyy" />
                            </div>

                            <div className="col-md-6">
                                <DatePicker
                                    className="form-control datepicker"
                                    selected={this.state.endDate}
                                    onChange={(e) => this.handleCheckOut(e)}
                                    dateFormat="EEEE, MMM d, yyyy" />
                            </div>
                        </div>

                        <br /> <br />

                        <form class="form" onSubmit={(e) => this.onAdd(e)}>

                            <div className="row">
                                <div className="col-md-6">
                                    <div class="form-group">
                                        <label for="exampleFormControlSelect1">Nights</label>
                                        <br />
                                        <select class="form-control" id="exampleFormControlSelect1"
                                            onChange={(e) => this.onNightsSelect(e)}
                                            value={this.state.nights}
                                        >
                                            <option>1</option>
                                            <option>2</option>
                                            <option>3</option>
                                            <option>4</option>
                                            <option>5</option>
                                        </select>
                                    </div>
                                </div>

                                <div className="col-md-6">
                                    <div class="form-group">
                                        <label for="exampleFormControlSelect1">Rooms</label>
                                        <br />
                                        <select class="form-control" id="exampleFormControlSelect1"
                                            value={this.state.rooms}
                                            onChange={(e) => this.onRoomSelect(e)}>
                                            <option>-</option>
                                            <option>1</option>
                                            <option>2</option>
                                            <option>3</option>
                                            <option>4</option>
                                            <option>5</option>
                                        </select>
                                    </div>
                                </div>

                            </div>
                            <div className="row">
                                <div className="col-md-12 text-right">
                                    <p>{this.state.rooms} Rooms, {this.state.nights} Nights</p>
                                </div>
                            </div>

                            <br /> <br />

                            <div className="row">
                                <div className="col-md-6 offset-6">
                                    <button type="submit" class="btn btn-success float-right">Add + </button>
                                </div>
                            </div>

                        </form>


                    </div>
                </div>
            </div>
        )
    }
}

const HotelDetails = connect(null, mapDispatchToProps)(FormReservation);
export default HotelDetails;

HotelDetails.propTypes = {
    rooms: PropTypes.number.isRequired,
    nights: PropTypes.number.isRequired,
    price: PropTypes.number.isRequired
}

商店

import { createStore } from "redux";
import rootReducer from "../reducers/index";
const store = createStore(rootReducer);
export default store;

操作

/*
 * constants 
 */

export const ADD_BOOKING = "ADD_BOOKING";
export const CONFIRM_ORDER = "CONFIRM_ORDER";
export const ADD_ORDER = "ADD_ORDER";

/*
 * action creators
 */

export const addBooking = payload => ({
  type: ADD_BOOKING,
  payload: payload
});

export const addOrder = payload => ({
  type: ADD_ORDER,
  payload: payload
});

export const confirmOrder = payload => ({
  type: CONFIRM_ORDER,
  payload: payload
});

减速器

const initialState = {
  bookings: [], 
  order: {}
};



function rootReducer(state = initialState, action) {
  if (action.type === ADD_BOOKING) {
    return Object.assign({}, state, {
      bookings: state.bookings.concat(action.payload)
    });
  }
  if (action.type === ADD_ORDER) {
    return Object.assign({}, state, {
      order: action.payload
    })
  }
  return state;
}
export default rootReducer;

这是该站点的演示

https://media.giphy.com/media/gLKPh0cxXepCVDB3NH/giphy.gif

0 个答案:

没有答案