2016-03-06 2 views
7

Я пытаюсь разработать форму панели, аналогичную форме листинга airbnb, чтобы глубже понять реакцию редукции, но я застрял в середине моего проекта. У меня есть несколько форм, где, когда пользователь нажимает кнопку продолжения, пользователь получает другую форму для заполнения и т. Д., И если пользователь нажимает кнопку «Назад», пользователь получит форму одного шага назад с ранее заполненными значениями. Я не мог решить, что я должен сделать для этого. Мне нужно создать объект в действии как listingName. резюме, имя, адрес электронной почты и т. д. как пустое значение и обновить его с помощью редуктора с помощью Object.assign() или что. До сих пор я мог только развиваться, как когда пользователь нажимает на личную вкладку, отображается форма, связанная с личной информацией, и когда пользователь нажимает на базовую вкладку, отображается форма, связанная с базовой информацией. Я хочу, чтобы все данные формы отправлялись на сервер при отправке. Что мне теперь делать ? Я использую действие приращения и уменьшения для кнопки «продолжить» и «Назад» и использовать действие отправки на последней кнопке формы? Не могли бы вы дать мне идею?Несколько форм регистрации с сокращением и реагированием

dashboard form

Вот мой код

действия/index.js

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

} 

редукторы/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; 
} 

редукторы/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} 
    ] 
} 

контейнеры/form-детали

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); 

ответ

1

Как вы используете реагируют-Redux вы можете использовать перевождь-форму. Это очень поможет вам в кодировании, поскольку это упростит вашу рабочую нагрузку, а также без ошибок (насколько я знаю). На мой взгляд, вы хотели бы использовать все библиотеки/фреймворки, предоставленные вам, как вы хотите быть как agile, насколько это возможно.

Кроме того, у редукционной формы есть реализация формы мастера. Я думаю, это именно то, что вы ищете.

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

Просто перейдите по ссылке, и вы увидите очень хороший учебник о том, как его реализовать. Должен быть кусок пирога.

+1

Я хотел сделать сам, так что я могу понять поток перевождь хорошо, и понять, что должно быть сделано в таких ситуации, как должны быть разработаны действия, редукторы. Во всяком случае спасибо за предложение. – pri

+0

вы можете сделать простой учебник, чтобы получить основы. Тогда вы просто хотите развиваться так быстро, как можете. Вещи не остаются такими, какие они есть надолго. Специально разработка front-end безумно быстро развивается. – Theo

+2

При изучении новой технологии существует огромная ценность в том, чтобы делать что-то с нуля. Вы просите о проблемах, если используете кучу инструментов, которые вы не понимаете, потому что второй ваш прецедент усложняется (или инструмент не работает так, как вы ожидаете), вы не знаете, что делать. –

5

Первое, что вам не хватает, это контролируемые компоненты. Предоставляя входы свойства value и функцию onChange, вы свяжете вход с внешним состоянием.

Ваши компоненты должны иметь доступ через реакцию-редукцию к состоянию и действиям. Форма value формы должна быть вашим состоянием для этого объекта. Таким образом, у вас может быть состояние:

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

Затем вы просто передадите каждое свойство на входные данные.Я предполагаю, что в этом примере, что вы прошли location опоры в mapStateToProps, и actions объекта со всеми соответствующими действиями в 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'}} 
    /> 
); 
} 

Вы обеспечиваете это действие, которое может использоваться для обновления состояние:

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

Затем вы просто слить его, в вашем редукторе

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

(с использованием динамического ключи и оператор распространения для аккуратности, но это похоже на Object.assign)

Все ваше состояние формы живет в магазине Redux таким образом. Когда вы будете готовы отправить эти данные на сервер, вы можете либо использовать асинхронные действия с redux-thunk, либо настроить middleware для выполнения вызовов. В любом случае стратегия такая же; ваше состояние длится локально и заполняет все ваши формы, а затем отправляется на сервер, когда пользователь отправляет.

Я прошел через это довольно быстро, дайте мне знать, если вам нужно мне остановиться на что-нибудь :)

+0

Спасибо, я попробую это и дам вам знать. Поэтому в моем редукторе должно быть расположено следующее: { listingName: '123 Main St', summary: 'Самое красивое место!' } личный: { \t OwnerName: 'Имя владельца', \t адрес электронной почты: 'Адрес электронной почты', \t PHONENUMBER: 'Номер телефона' } и предоставить обработчик события OnChange на все поле ввода, верно? – pri

+0

Для перехода формы при нажатии рядом и назад мне нужно предоставить различные действия (INCREMENT_FIELD и DECREMENT_FIELD)? – pri

+0

К первому комментарию: Да! Есть разные способы сделать это, но мне было проще сделать это, как я показал. Каждый вход получает тот же самый onChange обработчик, но с разными аргументами. Поскольку у вас есть «местоположение» и «личное» дерево, вы можете либо создать две функции, либо добавить третий аргумент. 'updateField ('location', 'listingName', val)' –