New to React-Redux.
I have a child component that uses the following with "handleSubmit" and this part of the code works.
<span
style={textLinkStyle}
onClick={handleSubmit(values =>
props.onSubmit({
...values,
sortBy: 'ClientNumber'
}
))}>
<span>Client # </span>
</span>
Here is the above code's child component with all the relevant parts.
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
So I wanted to separate repetative parts of this component into separate smaller components so I could reuse them. So the above component is now the parent of the following.
However it also has multiple submits one for sort direction up and one for sort direction down... I thought it would propagate all the way up to the top parent but alac alas.. no.
This is what I tried.
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>
)}
What I found is that handleSubmit works when it is used in the the TableHeader component as part of a larger parent component -its one level down. A first order child.
It does not work in the GlyphiconDirectionChange component. the second order child... Why?
I get the following error in the console
Exception: Call to Node module failed with error: TypeError: handleSubmit is not a function
This is a syntax error. How should I deal with the "handleSubmit" while also sending the updated values when its part of child that is also a child component.
So to recap. HandleSubmit works in the child but doesnt work in the the child component's child.. second level down...
EDIT
I note that #Dennis has suggested I use a despatch instead of using handleSubmit. This is the full 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)
It does have despatch which is where it goes to the reducer. Again.. if I want to componentize a form into many components one of which might be a header that is a link.. whats the best way to do this when it might be a component of a component of a parent component that at the moment is the only one that despatches...