2016-03-06 6 views
7

Ho cercato di sviluppare una forma di dashboard simile al modulo di elenco di airbnb per comprendere più profondamente la reazione al redux, ma sono bloccato nel bel mezzo del mio progetto. Ho un modulo multiplo in cui quando l'utente fa clic sul pulsante Continua l'utente otterrà un altro modulo da compilare e così via e se l'utente fa clic sul pulsante Indietro l'utente otterrà la forma di un passo indietro con valori precedentemente riempiti. Non potrei decidere cosa dovrei fare per questo. Devo creare un oggetto in azione come listingName. riepilogo, nome, email ecc. come valore vuoto e aggiornarlo con riduttore usando Object.assign() o cosa. Fino ad ora ho potuto svilupparmi come quando un utente fa clic sulla scheda personale viene mostrato un modulo relativo alle informazioni personali e quando l'utente fa clic sulla scheda di base, viene mostrato un modulo relativo alle informazioni di base. Voglio che tutti i dati del modulo vengano inviati al server al momento dell'invio. Cosa dovrei fare ora ? Uso l'azione di incremento e decremento per il pulsante continua e indietro e utilizzo l'azione di invio sull'ultimo pulsante del modulo? Potresti darmi un'idea per favore?Modulo di registrazione multiplo con redux e risposta

dashboard form

Ecco il mio codice

azioni/index.js

export function selectForm(form){ 
    return{ 
    type: 'FORM_SELECTED', 
    payload: form 
    }; 

} 

riduttori/reducer_active_form.js

export default function(state=null, action){ 
    let newState = Object.assign({},state); 
    switch(action.type){ 
    case 'FORM_SELECTED': 
     return action.payload; 
    } 
    return state; 
} 

riduttori/reducer_form_option.js

export default function(){ 
    return[ 
    { option: 'Personal Information', id:1}, 
    { option: 'Basic Information', id:2 }, 
    { option: 'Description', id:3}, 
    { option: 'Location', id:4}, 
    { option: 'Amenities', id:5}, 
    { option: 'Gallery', id:6} 
    ] 
} 

contenitori/form-dettagli

class FormDetail extends Component{ 
    renderPersonalInfo(){ 
    return(
     <div className="personalInfo"> 
     <div className="col-md-4"> 
      <label htmlFor='name'>Owner Name</label> 
      <input ref="name" type="textbox" className="form-control" id="name" placeholder="Owner name" /> 
     </div> 

     <div className="col-md-4"> 
      <label htmlFor="email">Email</label> 
      <input ref="email" type="email" className="form-control" id="email" placeholder="email" /> 
     </div> 

     <div className="col-md-4"> 
      <label htmlFor="phoneNumber">Phone Number</label> 
      <input ref="phone" type="textbox" className="form-control" id="phoneNumber" placeholder="phone number" /> 
     </div> 

     <div className="buttons"> 
      <button className="btn btn-primary">Continue</button> 
     </div> 

     </div> 
    ); 
    } 

    renderBasicInfo(){ 
    return(
     <div> 
       <h3>Help Rent seekers find the right fit</h3> 
       <p className="subtitle">People searching on Rental Space can filter by listing basics to find a space that matches their needs.</p> 
       <hr/> 
       <div className="col-md-4 basicForm"> 
        <label htmlFor="price">Property Type</label> 
        <select className="form-control" name="Property Type" ref="property"> 
         <option value="appartment">Appartment</option> 
         <option value="house">House</option> 
        </select> 
       </div> 
       <div className="col-md-4 basicForm"> 
        <label htmlFor="price">Price</label> 
        <input type="textbox" ref="price" className="form-control" id="price" placeholder="Enter Price" required /> 
       </div> 
       <div className="buttons"> 
       <button className="btn btn-primary">Back</button> 
       <button className="btn btn-primary">Continue</button> 
       </div> 
      </div> 
    ); 
    } 

    renderDescription(){ 
    return(
     <div> 
      <h3>Tell Rent Seekers about your space</h3> 
      <hr/> 
      <div className="col-md-6"> 
       <label htmlFor="listingName">Listing Name</label> 
       <input ref="name" type="textbox" className="form-control" id="listingName" placeholder="Be clear" /> 
      </div> 
      <div className="col-sm-6"> 
       <label htmlFor="summary">Summary</label> 
       <textarea ref="summary" className="form-control" id="summary" rows="3"></textarea> 
      </div> 
      <div className="buttons"> 
       <button className="btn btn-primary">Back</button> 
       <button className="btn btn-primary">Continue</button> 
      </div> 
     </div> 
    ); 
    } 

    renderLocation(){ 
    return(
     <div> 
      <h3>Help guests find your place</h3> 
      <p className="subtitle">will use this information to find a place that’s in the right spot.</p> 
      <hr/> 
      <div className="col-md-6"> 
       <label htmlFor="city">City</label> 
       <input ref="city" type="textbox" className="form-control" id="city" placeholder="Biratnagar" /> 
      </div> 
      <div className="col-md-6"> 
       <label htmlFor="placeName">Name of Place</label> 
       <input ref="place" type="textbox" className="form-control" id="placeName" placeholder="Ganesh Chowk" /> 
      </div> 
      <div className="buttons"> 
       <button className="btn btn-primary">Back</button> 
       <button className="btn btn-primary">Continue</button> 
      </div> 
     </div> 
    ); 
    } 

    render(){ 
    if (!this.props.form){ 
     return this.renderPersonalInfo(); 
    } 

    const type = this.props.form.option; 
    console.log('type is', type); 

    if (type === 'Personal Information'){ 
     return this.renderPersonalInfo(); 
    } 

    if (type === 'Basic Information'){ 
     return this.renderBasicInfo(); 
    } 

    if (type === 'Description'){ 
     return this.renderDescription(); 
    } 

    if (type === 'Location'){ 
     return this.renderLocation(); 
    } 
} 
} 

function mapStateToProps(state){ 

    return{ 
    form: state.activeForm 
    }; 
} 

export default connect(mapStateToProps)(FormDetail); 

risposta

1

Come si utilizza reagisce-redux è possibile utilizzare il Redux-modulo. Ti aiuterà molto con la codifica in quanto semplifica il tuo carico di lavoro ed è anche privo di errori (per quanto ne so). A mio parere, vorrai utilizzare tutte le librerie/framework forniti come desideri come agile il più possibile.

Anche il modulo di redux ha un'implementazione del modulo di procedura guidata. Penso che sia esattamente quello che stai cercando.

http://erikras.github.io/redux-form/#/examples/wizard?_k=yspolv

basta seguire il link e vedrete un ottimo tutorial su come implementarlo. Dovrebbe essere un pezzo di torta.

+1

che volevo fare da solo così posso capire il flusso di redux bene e capire cosa dovrebbe essere fatto in tale situazioni, come l'azione, i riduttori devono essere progettati. Comunque grazie per il suggerimento. – pri

+0

puoi fare il semplice tutorial per ottenere le basi. Quindi vuoi solo sviluppare il più velocemente possibile. Le cose non rimangono come sono a lungo. Specialmente lo sviluppo front-end è incredibilmente veloce. – Theo

+2

Quando apprendi una nuova tecnologia, c'è un enorme valore nel fare le cose da zero. Stai cercando guai se usi una serie di strumenti che non capisci, perché nel secondo caso il tuo caso d'uso diventa più complicato (o lo strumento non funziona come ti aspetti), non hai idea di cosa fare. –

5

La prima cosa che ti manca sono i componenti controllati. Dando agli input una proprietà value e una funzione onChange, collegherete l'input con uno stato esterno.

I componenti devono avere accesso, tramite react-redux, allo stato e alle azioni necessarie. Lo value del modulo dovrebbe essere il tuo stato per quell'oggetto. Quindi potresti avere uno stato come:

location: { 
    listingName: '123 Main St', 
    summary: 'The most beautiful place!' 
} 

Quindi, passeresti semplicemente ogni proprietà in input.Sto assumendo, in questo esempio, che hai superato il puntello location in mapStateToProps, e un oggetto actions con tutte le azioni correlate in mapDispatchToProps:

changeHandler(ev, fieldName) { 
    const val = ev.target.value; 
    this.props.actions.updateField(fieldName, val); 
}, 

render() { 
    return (
    <input 
     value={this.props.location.listingName} 
     onChange={(ev) => { this.changeHandler(ev, 'listingName'}} 
    /> 
); 
} 

si fornisce un'azione che può essere utilizzato per aggiornare stato:

function updatefield(field, val) { 
    return { 
    type: UPDATE_FIELD, 
    field, 
    val 
    }; 
} 

Poi, basta unire dentro, nel tuo riduttore

switch (action.type) { 
    case UPDATE_FIELD: 
    state = { ...state, [action.field]: val }; 

(usando dinamica le chiavi e l'operatore di spread per la pulizia, ma è simile a Object.assign)

Tutto lo stato del modulo vive nel negozio Redux in questo modo. Quando si è pronti a inviare tali dati al server, è possibile utilizzare le azioni asincrone con redux-thunk o configurare un numero middleware per eseguire le chiamate. Ad ogni modo, la strategia è la stessa; il tuo stato dura localmente e popola tutti i tuoi moduli, quindi viene inviato al server quando l'utente lo invia.

sono andato attraverso questo piuttosto veloce, fammi sapere se hai bisogno di elaborare su qualsiasi cosa :)

+0

Grazie ci proverò e ti faccio sapere. Quindi nel mio riduttore dovrebbe essere come questo: { listingName: 'Main Main', riassunto: "Il posto più bello!" } personali: { \t ownerName: 'nome del proprietario', \t-mail: 'indirizzo di posta elettronica', \t phoneNumber: 'il numero di telefono' } e fornire gestore di eventi onChange su tutto il campo di input, giusto? – pri

+0

Per la transizione del modulo mentre si fa clic su Avanti e Indietro, è necessario fornire un'azione diversa (INCREMENT_FIELD e DECREMENT_FIELD)? – pri

+0

Al tuo primo commento: Sì! Ci sono diversi modi per farlo, ma ho trovato più facile farlo come ho mostrato. Ogni input ottiene lo stesso gestore onChange, ma con argomenti diversi. Poiché hai un 'location' e un albero' personale', puoi creare due funzioni, oppure puoi aggiungere un terzo argomento. 'updateField ('location', 'listingName', val)' –