2017-04-19 25 views
0

React-Redux的新手。React Redux-Form使用包含多個提交子組件的子組件

我有一個子組件,它使用下面的「handleSubmit」和這部分代碼工作。

 <span 
     style={textLinkStyle} 
     onClick={handleSubmit(values => 
      props.onSubmit({ 
      ...values, 
      sortBy: 'ClientNumber' 
      } 
     ))}> 
     <span>Client # </span> 
     </span> 

這裏是上面的代碼的子組件與所有相關的部分。

export const TableHeaders = (props) => { 
    const { handleSubmit } = props 

    const { sortBy, sortDirection } = props 

    return (
    <div> 
     <div className="row"> 
     <div className="col-md-2" style={headingCellStyle}> 
      <span 
      style={textLinkStyle} 
      onClick={handleSubmit(values => 
       props.onSubmit({ 
       ...values, 
       sortBy: 'ClientNumber' 
       } 
      ))}> 
      <span>Client # </span> 
      </span> 

      <GlyphiconDirectionChange sortDirection={sortDirection}/> 
      ...... 

) 
} 
TableHeaders.propTypes = { 
    onSubmit: PropTypes.func.isRequired, 
} 

const TableHeadersForm = reduxForm({ 
    form: 'TableHeaders', 
})(TableHeaders) 

export default TableHeadersForm 

,所以我想這個組件的但卻難免重複部分分離成獨立的更小的組件,所以我可以重複使用。所以上面的組件現在是以下的父項。

但它也有多個提交一個用於排序方向向上和一個排序方向向下...我認爲它會一直傳播到頂端的父,但alac唉..不。

這就是我試過的。

const GlyphiconDirectionChange = (props) => { 
    const { handleSubmit } = props 
    const { sortDirection } = props 

    return (
    <span> 
     {sortDirection === 'Descending' ? 
     <span 
      style={textLinkStyle} 
      onClick={handleSubmit(values => 
      props.onSubmit({ 
       ...values, 
       sortDirection: 'Ascending' 
      } 
      ))} 
      className='glyphicon glyphicon-sort-by-attributes'> 
     </span> 
     : 
     <span 
      style={textLinkStyle} 
      onClick={handleSubmit(values => 
      props.onSubmit({ 
       ...values, 
       sortDirection: 'Descending' 
      } 
      ))} 
      className='glyphicon glyphicon-sort-by-attributes-alt'> 
     </span> 
     } 
    </span> 
)} 

我發現那是什麼時候的的tableHeader組件作爲一個更大的父組件的一部分handleSubmit作品 - 它的下一層。第一個訂單的孩子。

它在GlyphiconDirectionChange組件中不起作用。第二個孩子......爲什麼?

我得到以下錯誤控制檯

Exception: Call to Node module failed with error: TypeError: handleSubmit is not a function

這是一個語法錯誤。我應該如何處理「handleSubmit」,同時發送更新值時,它的子部分也是子組件。

所以回顧一下。 HandleSubmit工作的孩子,但不工作的子組件的孩子..第二級下調...

編輯

我注意到,#Dennis曾建議我用一個發貨,而不是使用handleSubmit的。這是完整的ClientsContainer:

import React, { Component, PropTypes } from 'react' 
import { connect } from 'react-redux' 
import Clients from './Clients' 
import SearchClients from './SearchClients' 
import TableHeaders from './TableHeaders' 
import { requestClients } from './reducer' 

class ClientsContainer extends Component { 
    static contextTypes = { 
    router: PropTypes.object.isRequired 
    } 

    componentDidMount() { 
    if (!this.props.isAuthorised) { 
     this.context.router.push('/') 
     return 
    } 

    this.fetchClients() 
    } 

    fetchClients = (values = {}) => { 
    const { currentPage, query, sortBy, sortDirection } = this.props 
    const searchParams = { 
     currentPage, 
     query, 
     sortBy, 
     sortDirection, 
     ...values, 
    } 
    console.log('fetchClients()!', values, searchParams) 
    this.props.requestClients(searchParams) 
    } 

    clientsSearch = (values = {}) => { 
    const { query, sortBy, sortDirection } = this.props 
    values.query = values.query || '' 
    const searchParams = { 
     query, 
     sortBy, 
     sortDirection, 
     ...values, 
     currentPage: 1, 
    } 
    console.log('clientsSearch()!', values, searchParams) 
    this.fetchClients(searchParams) 
    } 

    changeHeaders = (values = {}) => { 
    const { query, sortBy, sortDirection } = this.props 
    values.query = values.query || '' 
    const searchParams = { 
     query, 
     sortBy, 
     sortDirection, 
     ...values, 
     currentPage: 1, 
    } 
    console.log('changeHeaders()!', values, searchParams) 
    this.fetchClients(searchParams) 
    } 

    handlePageChanged = (pageIndex) => { 
    this.fetchClients({ 
     currentPage: pageIndex, 
    }) 
    } 

    render() { 
    const { clients, currentPage, query, sortBy, sortDirection, totalClients, totalPages } = this.props 

    return (
     <div className="row"> 
     <div className="col-md-12"> 
      <SearchClients onSubmit={this.clientsSearch} 
      currentPage={currentPage} 
      query={query} 
      sortBy={sortBy} 
      sortDirection={sortDirection} 
      /> 
      <TableHeaders onSubmit={this.changeHeaders} 
      currentPage={currentPage} 
      query={query} 
      sortBy={sortBy} 
      sortDirection={sortDirection} 
      /> 
      <Clients clients={clients} 
      currentPage={currentPage} 
      query={query} 
      sortBy={sortBy} 
      sortDirection={sortDirection} 
      totalClients={totalClients} 
      totalPages={totalPages} 
      onPageChanged={this.handlePageChanged} 
      /> 
     </div> 
     </div> 
    ) 
    } 
} 

const mapStateToProps = (state) => ({ 
    isAuthorised: state.login.isAuthorised, 
    clients: state.clients.clients, 
    currentPage: state.clients.currentPage, 
    query: state.clients.query, 
    sortBy: state.clients.sortBy, 
    sortDirection: state.clients.sortDirection, 
    totalClients: state.clients.totalClients, 
    totalPages: state.clients.totalPages, 
}) 
const mapDispatchToProps = (dispatch) => ({ 
    requestClients: (values) => dispatch(requestClients(values)), 
}) 
export default connect(mapStateToProps, mapDispatchToProps)(ClientsContainer) 

它確實有發送,它是減速機的地方。再次..如果我想組成一個表單到許多組件中,其中一個可能是一個鏈接的標題..什麼是最好的方式來做到這一點,當它可能是父組件的一個組件的組件是唯一一個派遣...

+0

我已經使用特定於您的用例的示例更新了原始答案。 – Dennis

回答

1

是否絕對有必要提交像排序方向的東西,或者是在某種程度上與您的後端相關?在我看來,這應該是客戶的責任。

把它放到客戶端還有一個額外的好處,使所有這一切變得更加簡單,因爲您可以在您想要更改排序方向時發送常規操作。然後,該操作可以按照請求的排序方向調用後端,並且可以相應地更新新狀態。

根據您處理的數據量的不同,您甚至可以選擇根本不打電話給您的後端,並將整個分揀留給客戶端。

關於你TableHeaders組件,這裏就是我會做:

有分量接受通過道具的事件處理函數,這樣你就可以通知容器時,在組件內部的排序變化。

這對於更小的組件來說很好,因爲你只是通過道具傳遞函數。

簡單的例子:

export const TableHeaders = (props) => { 
    const { onSortByChange, onSortDirectionChange } = props; 

    return (
    <div> 
     <span onClick={() => onSortByChange('ClientNumber')}>Client #</span> 
     <span onClick={() => onSortByChange('SomethingElse')}>Something else</span> 

     <GlyphiconDirectionChange onSortDirectionChange={onSortDirectionChange} /> 
    </div> 
); 
} 

const GlyphiconDirectionChange = (props) => { 
    const { onSortDirectionChange } = props; 

    return (
    <div> 
     <span onClick={() => onSortDirectionChange('asc')}>Asc</span> 
     <span onClick={() => onSortDirectionChange('desc')}>Desc</span> 
    </div> 
); 
} 

然後在你的容器,你可以這樣做:

class ClientsContainer extends Component { 
    handleSortDirection = (direction) => { 
    // Call Redux action to update your sort direction state 
    } 

    handleSortBy = (by) => { 
    // Call Redux action to update your sort by state 
    } 

    render() { 
    return (
     <div> 
     <TableHeaders 
      onSortByChange={this.handleSortBy} 
      onSortDirectionChange={this.handleSortDirection} 
      /* other props */ 
     /> 
     </div> 
    ); 
    } 
} 

爲了獲得新的數據,你可以實現componentWillUpdate並檢查排序或排序方向已經改變,如果是這樣,根據更新的道具獲取新數據。

但是,我覺得將它和數據提取部分從組件轉移到異步操作創建者會更優雅。這樣你的組件就沒有什麼責任了。

+0

Backend是一個ASP.NET API。後端爲搜索/過濾器排序和排序方向提供響應。它還提供分頁。當您點擊tableHeader組件中的標題時,我進行了排序工作。剝離標題和方向標記組件正在將我扼殺在這裏,因爲它現在是一個孩子的孩子。 – si2030

+0

這仍然很好,我實際上正在用C#WebApi後端工作一個類似的項目。我會去掉現在用於排序的'handleSubmit'東西,並且只是定期發送Redux動作。就像我說的,這些可以是(異步)動作創建者,接受排序方向,然後從API中獲取排序數據。然後,您可以使用新提取的數據更新商店。你的組件也會自動更新,因爲它的道具將被更新。 – Dennis

+0

我相信這是一個好方法,我會爲它投票。儘管GlyphiconDirection中的值的實際設置發生了變化,但我仍然遇到麻煩,因此ClientContainer中的ChangeHeaders(上述)功能可以使用設置值。我已經放置了控制檯日誌,它只是提出'ClientNumber'..給定有一些道具需要也包括在內(但不要改變)我應該得到類似於changeDirection()的consoleLog! Object {sortBy:「Client」} Object {query:「test」,sortBy:「LastName」,sortDirection:「Descending」,currentPage:1} .. – si2030