簡體   English   中英

Dispatch 不是函數,將從數據庫中刪除票證但拋出錯誤說 dispatch 不是函數

[英]Dispatch is not a function, will remove ticket from database but throws error saying dispatch is not a function

一切正常,當您單擊刪除按鈕時,它將刪除票證,但在 // 在票證操作中刪除票證時,它表示調度不是一個功能。 我試圖能夠刪除單擊的特定票證,並且還將添加一個編輯票證按鈕。

Tickets.js 更高級別

import React, { Fragment, useEffect } from 'react';
import PropTypes from 'prop-types';
import { connect } from 'react-redux';
import Spinner from '../layout/Spinner';
import TicketItem from './TicketItem';
import { getCurrentUsersTickets, deleteTickets } from '../../actions/tickets';

const Tickets = ({ getCurrentUsersTickets, tickets: { tickets, loading } }) => {
  useEffect(() => {
    getCurrentUsersTickets();
  }, []);

  return (
    <Fragment>
      {loading ? (
        <Spinner />
      ) : (
        <Fragment>
          <h1 className='large text-primary'>Your Active Tickets</h1>
          <div className='container'>
            {tickets.length > 0 ? (
              tickets.map(tickets => (
                <TicketItem
                  key={tickets._id}
                  tickets={tickets}
                  deleteTickets={deleteTickets}
                />
              ))
            ) : (
              <h4>No tickets found...</h4>
            )}
          </div>
        </Fragment>
      )}
    </Fragment>
  );
};

Tickets.propTypes = {
  getCurrentUsersTickets: PropTypes.func.isRequired,
  tickets: PropTypes.object.isRequired,
  deleteTickets: PropTypes.func.isRequired
};

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

export default connect(mapStateToProps, {
  getCurrentUsersTickets,
  deleteTickets
})(Tickets);

Ticketitems.js 子組件

import React from 'react';
import { Link } from 'react-router-dom';
import PropTypes from 'prop-types';

const TicketItem = ({
  tickets: {
    _id,
    title,
    fromBuilding,
    fromRoom,
    toBuilding,
    toRoom,
    contactNumber,
    description,
    reasonForMove
  },
  deleteTickets
}) => {
  return (
    <div className='accordion' id={`userTickets${_id}`}>
      <div className='card'>
        <div className='card-header' id={`userTicketsHeading${_id}`}>
          <h2 className='mb-0'>
            <button
              className='btn btn-link'
              type='button'
              data-toggle='collapse'
              data-target={`#collapse${_id}`}
              aria-expanded='true'
              aria-controls={`collapse${_id}`}
            >
              {title}
            </button>
          </h2>
        </div>

        <div
          id={`collapse${_id}`}
          className='collapse'
          aria-labelledby={`userTicketsHeading${_id}`}
          data-parent={`#userTickets${_id}`}
        >
          <div className='card-body'>
            <ul>
              <li>
                <span className='font-weight-bolder'>From Building:</span>{' '}
                {fromBuilding}
              </li>
              <li>
                <span className='font-weight-bolder'>From Room:</span>{' '}
                {fromRoom}
              </li>
              <li>
                <span className='font-weight-bolder'>To Building:</span>{' '}
                {toBuilding}
              </li>
              <li>
                <span className='font-weight-bolder'>To Building:</span>{' '}
                {toRoom}
              </li>
              <li>
                <span className='font-weight-bolder'>Contact Number:</span>{' '}
                {contactNumber}
              </li>
              <li>
                <span className='font-weight-bolder'>Description:</span>{' '}
                {description}
              </li>
              <li>
                <span className='font-weight-bolder'>Reason For Move:</span>{' '}
                {reasonForMove}
              </li>
            </ul>
            <button className='btn btn-danger' onClick={deleteTickets(_id)}>
              Delete Ticket
            </button>
          </div>
        </div>
      </div>
    </div>
  );
};

TicketItem.propTypes = {
  tickets: PropTypes.object.isRequired,
  deleteTickets: PropTypes.func.isRequired
};

export default TicketItem;

票務操作

import axios from 'axios';
import { setAlert } from './alert';

import { GET_USERS_TICKETS, TICKETS_ERROR, DELETE_TICKETS } from './types';

// Get tickets
export const getCurrentUsersTickets = () => async dispatch => {
  try {
    const res = await axios.get('/api/tickets/me');

    dispatch({
      type: GET_USERS_TICKETS,
      payload: res.data
    });
  } catch (err) {
    dispatch({
      type: TICKETS_ERROR,
      payload: { msg: err.response.statusText, status: err.response.status }
    });
  }
};

// Create
export const createTickets = (formData, history) => async dispatch => {
  try {
    const config = {
      headers: {
        'Content-Type': 'application/json'
      }
    };

    const res = await axios.post('/api/tickets', formData, config);

    dispatch({
      type: GET_USERS_TICKETS,
      payload: res.data
    });

    history.push('/dashboard');
  } catch (err) {
    const errors = err.response.data.errors;

    if (errors) {
      errors.forEach(error => dispatch(setAlert(error.msg, 'danger')));
    }

    dispatch({
      type: TICKETS_ERROR,
      payload: { msg: err.response.statusText, status: err.response.status }
    });
  }
};

// Delete ticket
export const deleteTickets = id => async dispatch => {
  try {
    await axios.delete(`/api/tickets/delete/${id}`);

    dispatch({
      type: DELETE_TICKETS,
      payload: id
    });
  } catch (err) {
    console.log('err response', err);
    // dispatch({
    //   type: TICKETS_ERROR,
    //   payload: { msg: err.response.statusText, status: err.response.status }
    // });
  }
};

減票器

import {
  GET_USERS_TICKETS,
  TICKETS_ERROR,
  CLEAR_TICKETS,
  DELETE_TICKETS
} from '../actions/types';

const initialState = {
  tickets: [],
  loading: true,
  error: {}
};

export default function(state = initialState, action) {
  const { type, payload } = action;

  switch (type) {
    case GET_USERS_TICKETS:
      return {
        ...state,
        tickets: payload,
        loading: false
      };
    case TICKETS_ERROR:
      return {
        ...state,
        error: payload,
        loading: false
      };
    case CLEAR_TICKETS:
      return {
        ...state,
        tickets: [],
        loading: false
      };
    case DELETE_TICKETS:
      return {
        ...state,
        tickets: state.tickets.filter(
          tickets => tickets._id !== action.payload
        ),
        loading: false
      };
    default:
      return state;
  }
}

我認為,由於您在 Redux 操作中使用異步調用,因此您需要使用 Redux 中間件來處理承諾,例如Redux-PromiseRedux-Thunk

我忘記將 deleteTickets 操作作為一個道具放在 Ticket 組件上,以便它可以傳遞到返回部分中以轉到子組件。 然后在 TicketItem.js 上,需要 onClick={() => deleteTickets(_id)} 的刪除按鈕的格式錯誤。 可能修復的深夜和隧道視覺錯過了簡單的修復

門票.js

import React, { Fragment, useEffect } from 'react';
import PropTypes from 'prop-types';
import { connect } from 'react-redux';
import Spinner from '../layout/Spinner';
import TicketItem from './TicketItem';
import { getCurrentUsersTickets, deleteTickets } from '../../actions/tickets';

const Tickets = ({
  getCurrentUsersTickets,
  tickets: { tickets, loading },
  // added deleteTickets  
  deleteTickets
}) => {
  useEffect(() => {
    getCurrentUsersTickets();
  }, []);

  return (
    <Fragment>
      {loading ? (
        <Spinner />
      ) : (
        <Fragment>
          <h1 className='large text-primary'>Your Active Tickets</h1>
          <div className='container'>
            {tickets.length > 0 ? (
              tickets.map(tickets => (
                <TicketItem
                  key={tickets._id}
                  tickets={tickets}
                  deleteTickets={deleteTickets}
                />
              ))
            ) : (
              <h4>No tickets found...</h4>
            )}
          </div>
        </Fragment>
      )}
    </Fragment>
  );
};

Tickets.propTypes = {
  getCurrentUsersTickets: PropTypes.func.isRequired,
  tickets: PropTypes.object.isRequired,
  deleteTickets: PropTypes.func.isRequired
};

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

export default connect(mapStateToProps, {
  getCurrentUsersTickets,
  deleteTickets
})(Tickets);

票據項.js

import React from 'react';
import { Link } from 'react-router-dom';
import PropTypes from 'prop-types';

const TicketItem = ({
  tickets: {
    _id,
    title,
    fromBuilding,
    fromRoom,
    toBuilding,
    toRoom,
    contactNumber,
    description,
    reasonForMove
  },
  deleteTickets
}) => {
  return (
    <div className='accordion' id={`userTickets${_id}`}>
      <div className='card'>
        <div className='card-header' id={`userTicketsHeading${_id}`}>
          <h2 className='mb-0'>
            <button
              className='btn btn-link'
              type='button'
              data-toggle='collapse'
              data-target={`#collapse${_id}`}
              aria-expanded='true'
              aria-controls={`collapse${_id}`}
            >
              {title}
            </button>
          </h2>
        </div>

        <div
          id={`collapse${_id}`}
          className='collapse'
          aria-labelledby={`userTicketsHeading${_id}`}
          data-parent={`#userTickets${_id}`}
        >
          <div className='card-body'>
            <ul>
              <li>
                <span className='font-weight-bolder'>From Building:</span>{' '}
                {fromBuilding}
              </li>
              <li>
                <span className='font-weight-bolder'>From Room:</span>{' '}
                {fromRoom}
              </li>
              <li>
                <span className='font-weight-bolder'>To Building:</span>{' '}
                {toBuilding}
              </li>
              <li>
                <span className='font-weight-bolder'>To Building:</span>{' '}
                {toRoom}
              </li>
              <li>
                <span className='font-weight-bolder'>Contact Number:</span>{' '}
                {contactNumber}
              </li>
              <li>
                <span className='font-weight-bolder'>Description:</span>{' '}
                {description}
              </li>
              <li>
                <span className='font-weight-bolder'>Reason For Move:</span>{' '}
                {reasonForMove}
              </li>
            </ul>
            <button
              className='btn btn-danger'
              // Reformated onClick
              onClick={() => deleteTickets(_id)}
            >
              Delete Ticket
            </button>
          </div>
        </div>
      </div>
    </div>
  );
};

TicketItem.propTypes = {
  tickets: PropTypes.object.isRequired,
  deleteTickets: PropTypes.func.isRequired
};

export default TicketItem;

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM