2017-12-04 4 views
1

react-reduxを使って簡単なアポイントメントアプリを作ろうとしているときに、アクション内の1つの項目(ラストネーム)が定義されていないエラーが発生します。他の2つの項目(firstnameとid)は適切に定義されています。なぜこのアクション項目は定義されておらず、他は定義されていますか?私はreact-reduxの重要な概念が欠けていると感じています。アクションが定義されていない理由とそれを修正する方法を説明できますか? アクション作成者:react-reduxのaction-creator関数でアクションが定義されていないのはなぜですか?

import { ADD_BOOKING, DELETE_BOOKING } from "../constants"; 

const uid =() => Math.random().toString(34) 

export const addBooking=function (firstname,lastname){ 

    const action={ 
     type:ADD_BOOKING, 
     payload:{firstname,  
       lastname, 
       id:uid() 

     } 
    } 
console.log('action in addBooking',action); 
return action; 
} 

export const deleteBooking = (id) => { 
    const action = { 
     type: DELETE_BOOKING, 
     id: id 
    }; 
    console.log("deleting in actions", action); 
    return action; 
}; 

減速:

import { ADD_BOOKING, DELETE_BOOKING} from "../constants"; 


const booking = action => { 
    return { 
     firstname: action.payload.firstname, 
     lastname: action.payload.lastname, 
     id: action.payload.id 
    }; 
}; 

const removeById = (state = [], id) => { 
    //filter those not clicked 
    const bookings = state.filter(booking => booking.id !==id); 
    console.log("new reduced bookings", bookings); 
    return bookings; 
}; 

const bookings = (state = [], action) => { 
    let bookings = null; 
    switch (action.type) { 
     case ADD_BOOKING: 
      bookings = [...state, booking(action)]; 
      console.log("bookings as state", bookings); 
      return bookings; 
     case DELETE_BOOKING: 
      bookings = removeById(state, action.id); 
      return bookings; 

     default: 
      return state; 
    } 
}; 
export {bookings}; 

コンソールログ: console log:

コンポーネント(App.jsx):

import React, { Component } from "react"; 
import "./App.css"; 
import "bootstrap/dist/css/bootstrap.min.css"; 
import { addBooking, deleteBooking } from "../actions"; 
import { Header } from "./NavigationBar"; 
import { connect } from "react-redux"; 

class App extends Component { 
    //Initialize the Component 
    constructor(props) { 
    super(props); 
    this.state = { 
     firstname: "", 
     lastname: "", 
     duedate: "" 
    }; 
    } 
    //add Booking 
    addBooking() { 
    this.props.addBooking(this.state.firstname); 
    this.props.addBooking(this.state.lastname); 

    } 

    //delete Booking 
    deleteBooking(id) { 
    this.props.deleteBooking(id); 
    } 
    //render the bookings 
    renderBookings() { 
    //access our bookings 

    const {bookings} = this.props; 

    return (
     <ul className="list-group col-sm-4"> 
     { bookings.map(booking => { 
      return (<li key={ booking.id } className="list-group item"> 
         <div className="list-item"> 
         { booking.firstname } 
         </div> 
         <div className="list-item"> 
         { booking.lastname } 
         </div> 

         <div className="btn btn-danger" onClick={() => this.deleteBooking(booking.id) }> 
         Cancel Booking 

         </div> 
        </li>) 
      }) } 
     </ul>) 
    } 
    render() { 
    return (
     <div className="App"> 
     <Header /> 
     <div className="form-inline booking-form"> 
      <div className="form-group"> 
      <input 
       className="form-control" 
       placeholder="Enter First Name" 
       onChange={event => 
       this.setState({ 
        firstname: event.target.value 
       }) 
       } 
      /> 
      <input 
       className="form-control" 
       placeholder="Enter Last Name" 
       onChange={event => 
       this.setState({ 
        lastname: event.target.value 
       }) 
       } 
      /> 
      <input 
       className="form-control" 
       type="datetime-local" 
       onChange={event => 
       this.setState({ 
        duedate: event.target.value 
       }) 
       } 
      /> 

      <button 
       type="button" 
       className="btn btn-success" 
       onClick={() => this.addBooking()} 
      > 
       Add Booking 
      </button> 
      </div> 
     </div> 
     {this.renderBookings()} 
     </div> 
    ); 
    } 
} 

function mapStateToProps(state) { 
    return { 
    bookings: state 
    }; 
} 

export default connect(mapStateToProps, { 
    addBooking, 
    deleteBooking 
})(App); 
+0

このコードから、なぜそれが起こっているのかわかりません。あなたの行動が派遣されている場所では、おそらく問題になります。アクションがディスパッチされているコンポーネントからコードを投稿できますか? –

+0

@Austin Greco私はApp.jsxを追加しました。私の理解のディスパッチアクションは限られています。 – Kaleab

+0

App.jsxの 'addBooking'関数は、' addBooking'アクションを唯一の入力としてファーストネームで、次に唯一の入力としてラストネームで呼び出します。最初の入力は、常にあなたがアクションを定義した方法であるので、常にファーストネームになります。物事をまっすぐに保つために、一般的な機能にはアクションとは異なる名前を付けるほうが簡単かもしれません。 – mef79

答えて

1

addBooking関数は1つのパラメータで呼び出されますが、2回呼び出すことができます。各値がfirstnameに割り当てられた2つのアクションを返します。代わりに、これを行ってください:this.props.addBooking(this.state.firstname, this.state.lastname);。それがあなたの問題を解決します。

+0

アクションはdispatch()内でディスパッチされます。 Reduxについては、[documentation](https://redux.js.org/docs/basics/Actions.html)を参照してください。 –

+0

この場合のように、ディスパッチをバインドするconnectを使用しない限り。 – gretro

+0

ああ、私はconnectが第2引数としてアクションクリエイターを雇ったことを知らなかった! TIL –

0

あなたがAppをラップしているので、 connectAppにはdispatchアクションが追加されました。 dispatchthis.props.dispatchの小道具でアクセスできます。代わりにthis.props.addBookingの代わりにthis.props.dispatch(addBooking())を使用してください。

また、あなたが接続here

export default connect()(App) 

詳細に

export default connect(mapStateToProps, { 
    addBooking, 
    deleteBooking 
})(App); 

を編集することができます。 Connectは、店舗の特定の部分を選び、包み込んでいるコンポーネントにそれらを公開します。この場合、あなたはあなたのアクションを使いたいだけで、App.jsxの上にそれらをインポートします

addBooking()/ deleteBooking()を呼び出しても、正しいチャンネル(dispatch)を流れていません。 Reduxがストアを更新することを知っているので、値は未定義に戻ります。

+0

他の値 "firstname"と "id"がレンダリングされました。 @グレトーの答えは問題を解決しましたが、ディスパッチを省略するとどのような影響がありますか? – Kaleab

関連する問題