2016-02-18 13 views
7

Tôi có hai thành phần: một thành phần vùng chứa và một thành phần trình bày.Đọc <input> trong thành phần chức năng (không quốc tịch)

Vùng chứa tìm nạp tất cả thông tin và hành động cần thiết để hiển thị Bài đăng bằng cách sử dụng thành phần thuyết trình. Trên thành phần thuyết trình tôi có một cách để tôi có thể chuyển đổi giữa việc trình bày thông tin và chỉnh sửa nó. Khi tôi chỉnh sửa và gửi dữ liệu về bài đăng, tôi muốn đọc các giá trị từ tất cả các yếu tố đầu vào khác nhau mà tôi có để tôi có thể gửi một hành động.

Tuy nhiên, các yếu tố đầu vào là không phải bên trong thẻ <form id='theForm' onSubmit={onHandleSubmit}>. Thay vào đó, tất cả các số <input><button type='submit'> nằm ngoài số <form> có thuộc tính form='theForm'.

Tôi nghĩ rằng tôi có thể có nhiều <input> ngoài hình thức, nhưng miễn là thuộc tính form chỉ về phía <form> tương ứng, tôi có thể đọc nó giá trị sử dụng trường hợp handleOnSubmit (e) {...} nhận được. Tuy nhiên, tôi đã không tìm ra cách để làm điều đó.

Làm cách nào để đọc giá trị của các yếu tố đầu vào trên chức năng handleOnSubmit? Hoặc đây là một ý tưởng hoàn toàn sai lầm tôi nên từ bỏ?

// PostSummaryContainer.js 
import React, { PropTypes, Component } from 'react' 
import { connect } from 'react-redux' 

import { loadPost, editPost, editPostCancel, editPostSubmit } from '../../actions/posts' 

import PostSummaryView from '../../views/details/summary' 

class PostSummaryContainer extends Component { 
    constructor (props) { 
    super(props) 
    this.handleOnSubmit = this.handleOnSubmit.bind(this) 
    this.handleOnCancel = this.handleOnCancel.bind(this) 
    this.handleOnSubmit = this.handleOnSubmit.bind(this) 
    } 

    handleOnEdit (e) { 
    e.preventDefault() 
    this.props.editPost() 
    } 

    handleOnCancel (e) { 
    e.preventDefault() 
    this.props.editPostCancel() 
    } 

    handleOnSubmit (e) { 
    e.preventDefault() 

    // How do I read the input values? <-------------------- 
    } 

    componentWillMount() { 
    const { 
     id, 
     loadPost 
    } = this.props 

    loadPost(id) 
    } 

    render() { 
    const { 
     post, 
     isLoading, 
     isEditing 
    } = this.props 

    const viewProps = { 
     bacon, 
     isLoading, 
     isEditing, 
     handleOnEdit: this.handleOnEdit, 
     handleOnCancel: this.handleOnCancel, 
     handleOnSubmit: this.handleOnSubmit 
    } 

    return (
     <PostSummaryView {...viewProps} /> 
    ) 
    } 
} 

const mapStateToProps = (state, ownProps) => { 
    const { 
    params: { 
     id 
    } 
    } = ownProps 

    const post = state.entities.post[id] 

    const { 
    isLoading, 
    isEditing 
    } = state.posts 

    return { 
    id, 
    post, 
    isLoading, 
    isEditing 
    } 
} 

export default connect(
    mapStateToProps, 
    { loadPost, editPost, editPostCancel, editPostSubmit } 
)(PostSummaryContainer) 

Mở phần trình bày của tôi:

// PostSummmaryView.js 
import React from 'react' 
import moment from 'moment' 

function PostSummaryView (props) { 
    const { 
    post, 
    isLoading, 
    isEditing, 
    handleOnEdit, 
    handleOnCancel, 
    handleOnSubmit 
    } = props 

    const formId = 'editPostForm' 

    return (
    isLoading 
     ? <div>Loading...</div> 
     : <div className='row'> 
      {isEditing && <form id={formId} onSubmit={handleOnSubmit}><input type='text' name='name' /></form>} 

      <div className='col-md-6'> 
      <img src={post.media.url} className='img-responsive' /> 
      {isEditing && <input type='file' name='media' form={formId}/>} 
      </div> 
      <div className='col-md-6'> 

      <h1>{post.name}</h1> 
      <p> 
       {moment(post.publicationDate).format('dddd, MMMM Do')} 
      </p> 

      <hr /> 

      <p className='text-left'> 
       {post.description || 'Lorem ipsum dolor sit amet, consectetur adipisici elit...'} 
      </p> 

      {isEditing 
       ? <div> 
        <button className='btn btn-lg btn-default' onClick={handleOnCancel}>Cancel</button> 
        <button type='submit' className='btn btn-lg btn-default' form={formId}>Submit</button> 
       </div> 
       : <button className='btn btn-lg btn-default' onClick={handleOnEdit}>Edit</button> 
      } 

      </div> 
     </div> 
) 
} 

export default PostSummaryView 

Trả lời

5

Disclaimer: Tôi vẫn còn mới để Phản ứng/Redux, vì vậy hãy trả lời này với một lớn hạt muối.

Tôi nghĩ rằng cách tiếp cận của bạn là hơi tắt, trong đó bạn không cần phải đi xung quanh và thu thập bất kỳ dữ liệu từ đầu vào khi nộp (cho dù là trong hay ngoài <form>). Tiểu bang của bạn phải luôn ở trong một vị trí trung tâm, hợp nhất.

Nếu bạn cung cấp tùy chọn Hủy, hãy cập nhật dữ liệu Đăng trong phần Chỉnh sửa trong một phần riêng biệt của tiểu bang (IMHO) hơn là sửa đổi trực tiếp dữ liệu "nguồn".

Bạn có thể tạo trình giảm tốc cho biểu mẫu Chỉnh sửa bài đăng giúp giữ các cặp khóa/giá trị cho các trường nhập.

Khi người dùng bắt đầu chỉnh sửa, bạn có thể sao chép dữ liệu Bài đăng gốc vào phần mới này của tiểu bang cụ thể cho biểu mẫu Chỉnh sửa. Khi người dùng thay đổi các đầu vào, bạn có thể gửi các hành động nói "hey, trường mẫu X đã được thay đổi thành giá trị Y", có thể được giảm xuống trạng thái mà không cần sửa đổi dữ liệu Bài đăng gốc. Pseudo-code ví dụ về đối tượng trạng thái ở dòng này:

{ 
    // The actual Post data 
    post: { 
     media: {...}, 
     title: "My First Post", 
     publicationDate: 1455768160589, 
     description: "Lorem ipsum dolor sit amet"     
    }, 

    // The temporary Post data in the Edit form 
    postForm: { 
     media: {...}, 
     title: "My Turbo-Charged First Post", 
     publicationDate: 1455769951276, 
     description: "Updated description yadda blah"     
    } 
} 

Sau đó, trong phần trình bày của bạn, bạn có thể lái xe đầu vào giá trị tắt postForm thay vì post.

Mỗi đầu vào sẽ được cung cấp chức năng xử lý thay đổi để cập nhật ngay lập tức được phản ánh trong trạng thái (hoặc không phản ánh, tùy thuộc vào logic/bộ giảm tốc xác thực của bạn). tức là:

// In your actions associated with `Post` 
// ------------------------------------------ 
function updateForm(field, value) { 
    return { 
     type: UPDATE_FORM, 
     field, 
     value 
    } 
} 

// In your container 
// ------------------------------------------ 
handleOnEdit(event) { 
    postActions.updateForm(event.target.name, event.target.value) 
} 

// In your reducer 
// ------------------------------------------ 
switch (action.type) { 
    case UPDATE_FORM: 
     return { 
      ...state, 
      [action.field]: action.value 
     } 
} 

// In your presentational component's render() method 
// ------------------------------------------ 
const {postForm, handleOnEdit} = this.props 
const descriptionMarkup = (
    isEditing 
    ? <input type='text' name='description' value={postForm.description} onChange={handleOnEdit} /> 
    : (post.description || 'Lorem ipsum dolor sit amet, consectetur adipisici elit...') 
) 
// ... 
<p className='text-left'> 
    {descriptionMarkup} 
</p> 

Nếu bạn làm theo mô hình này (! Và một lần nữa, không chắc chắn đó là "đúng"), nộp mẫu đơn trở nên đơn giản như làm một cái gì đó với đối tượng postForm của tiểu bang. Đối tượng đó phải luôn phản ánh các giá trị đầu vào của biểu mẫu mới nhất và lớn nhất.

Hủy biểu mẫu trở nên đơn giản như đặt phần postForm của cây trạng thái thành {}. Dữ liệu Đăng gốc vẫn giữ nguyên.

Hope this helps chạy bộ một số ý tưởng ...

Một số ví dụ khác/phương pháp tiếp cận bạn có thể thử:

+1

Ah. Điều này có vẻ như là một ý tưởng tốt để thử. Ngày mai tôi sẽ kiểm tra nó và báo cáo lại với nó như thế nào. Cảm ơn! – Sparragus

+1

Tôi đã thử triển khai thực hiện điều này hoặc sử dụng biểu mẫu redux. Tôi đã có một thời gian khó khăn với tài liệu của redux-form nên tôi đã từ bỏ nó. Và tôi sẽ khám phá ý tưởng của bạn cho một dự án tương lai. Cuối cùng tôi đã kết thúc refactoring mã của tôi từ các thành phần chức năng để lớp X mở rộng thành phần và đọc các đầu vào trở thành và nhiệm vụ dễ dàng hơn. Tôi cũng đã loại bỏ các

và các thuộc tính biểu mẫu. Dù sao cũng cảm ơn! – Sparragus

+0

Tuyệt vời, có vẻ như một trải nghiệm học tập tốt - bất kỳ cơ hội nào bạn có thể cập nhật câu hỏi của mình với giải pháp được cấu trúc lại? – rkd

Các vấn đề liên quan