Last active
June 22, 2017 14:16
-
-
Save linxlad/3e395cacc83f4dfd18cb942a30bdcc93 to your computer and use it in GitHub Desktop.
React Form Redux Example
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import axios from 'axios'; | |
import { | |
ADD_EMAIL_STARTED, | |
ADD_EMAIL_FINISHED | |
} from '../types'; | |
/** | |
* Do not use hasError callback if you are using | |
* componentWillReceiveProps in component. | |
* @param email | |
* @param hasError | |
* @return {function(*)} | |
*/ | |
export const addEmail = (email, hasError) => { | |
return dispatch => { | |
dispatch({type: ADD_EMAIL_STARTED}); | |
const instance = axios.create({ | |
baseURL: '/api', | |
timeout: 10000, | |
headers: {'Content-Type': 'application/json'}, | |
responseType: 'json' | |
}); | |
instance.put('/user/email', email) | |
.then((response) => { | |
hasError(false); | |
dispatch({ | |
type: ADD_EMAIL_FINISHED, | |
payload: response.data, | |
error: false, | |
meta: response.meta | |
}); | |
}) | |
.catch((error) => { | |
if (error.response) { | |
dispatch({type: ADD_EMAIL_FINISHED, | |
payload: error.response.data.errors, | |
error: true | |
}); | |
} else { | |
dispatch({ | |
type: ADD_EMAIL_FINISHED, payload: ['Failed to add email.'], | |
error: true | |
}); | |
} | |
hasError(true); | |
}); | |
}; | |
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import { | |
ADD_EMAIL_STARTED, | |
ADD_EMAIL_FINISHED | |
} from '../types'; | |
const initialState = { | |
loading: false, | |
payload: null, | |
error: false, | |
meta: null | |
}; | |
export const addEmailReducer = (state = initialState, action) => { | |
switch (action.type) { | |
case ADD_EMAIL_STARTED: | |
return { | |
...state, | |
loading: true | |
}; | |
case ADD_EMAIL_FINISHED: | |
return { | |
...state, | |
loading: false, | |
payload: action.payload, | |
error: action.error, | |
meta: action.meta || initialState.meta | |
}; | |
default: | |
return state; | |
} | |
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import React, { Component } from 'react'; | |
import { Form, Input, Button, Row, Col } from 'antd'; | |
import { bindActionCreators } from 'redux'; | |
import { connect } from 'react-redux'; | |
import { EmailTable } from '../../EmailTable'; | |
import { addEmail } from '../../../actions'; | |
import { notify, errorsToList } from '../../../helpers'; | |
import styles from './style.less'; | |
const FormItem = Form.Item; | |
class ManageEmailAccountsFormComponent extends Component { | |
/** | |
* @param event | |
*/ | |
handleSubmit = (event) => { | |
event.preventDefault(); | |
const { form } = this.props; | |
form.validateFields((errors, values) => { | |
if (!errors) { | |
this.props.addEmail( | |
{email: values.email}, | |
(hasError) => this.displayNotification(hasError) | |
); | |
} | |
}); | |
}; | |
/** | |
* @param hasError | |
*/ | |
displayNotification = (hasError) => { | |
const { addAccountEmail, form } = this.props; | |
form.resetFields(); | |
if (hasError) { | |
notify('error', errorsToList('Add account email', addAccountEmail.payload)); | |
} else { | |
notify('success', 'Successfully added email.'); | |
} | |
}; | |
getSortedEmails = () => { | |
const { profile } = this.props; | |
return profile.email.map((value, key) => { | |
return { | |
key: key, | |
email: value.address, | |
primary: profile.primary_email === value.address, | |
activated: value.verified | |
}; | |
}).sort((a, b) => { | |
return b.primary - a.primary; | |
}); | |
}; | |
/** | |
* OPTIONAL WAY AS APPOSED TO THE CALL BACK ON this.props.addEmail. | |
* This method keeps the reducer clean of any callbacks. | |
* @param nextProps | |
*/ | |
// componentWillReceiveProps(nextProps) { | |
// const { addAccountEmail } = this.props; | |
// | |
// if (nextProps.addAccountEmail && nextProps.addAccountEmail !== addAccountEmail) { | |
// if (addAccountEmail.error) { | |
// notify('error', errorsToList('Add account email', addAccountEmail.payload)); | |
// } else if (addAccountEmail.payload !== null) { | |
// notify('success', 'Successfully added email.'); | |
// } | |
// } | |
// } | |
/** | |
* @return {XML} | |
*/ | |
render() { | |
const { getFieldDecorator } = this.props.form; | |
const { addAccountEmail } = this.props; | |
return ( | |
<div className={styles.emailAccountContent}> | |
<h3>Available accounts</h3> | |
<p>The table below lists the email accounts you have set up.</p> | |
<EmailTable loading={false} dataSource={this.getSortedEmails()} /> | |
<h3>Add new email account</h3> | |
<p>Enter the address of the email account you wish to add. A validation token will be sent to this address which you will need to finalise the addition of this account.</p> | |
<Form onSubmit={this.handleSubmit} className={styles.form}> | |
<Row gutter={16}> | |
<Col span={18}> | |
<FormItem> | |
{getFieldDecorator('email', { | |
rules: [ | |
{ required: true, message: 'Please enter your email' }, | |
{ type: 'email', message: 'Please enter a valid email' } | |
] | |
})( | |
<Input type="email" /> | |
)} | |
</FormItem> | |
</Col> | |
<Col span={4}> | |
<FormItem> | |
<Button | |
type="primary" | |
htmlType="submit" | |
size="large" | |
loading={addAccountEmail.loading} | |
className=""> | |
Add | |
</Button> | |
</FormItem> | |
</Col> | |
</Row> | |
</Form> | |
</div> | |
); | |
} | |
} | |
/** | |
* @param state | |
* @return {{profile: *, addAccountEmail: *}} | |
*/ | |
const mapStateToProps = (state) => { | |
const { | |
profileFetchSuccess, | |
addAccountEmail | |
} = state; | |
return { | |
profile: profileFetchSuccess, | |
addAccountEmail | |
}; | |
}; | |
/** | |
* | |
* @param dispatch | |
* @return {{addEmail: addEmail}|B|N} | |
*/ | |
const mapDispatchToProps = (dispatch) => { | |
return bindActionCreators({ | |
addEmail | |
}, dispatch); | |
}; | |
export const ManageEmailAccountsForm = connect(mapStateToProps, mapDispatchToProps)(Form.create()(ManageEmailAccountsFormComponent)); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* Add email to account types. | |
* @type {string} | |
*/ | |
export const ADD_EMAIL_STARTED = 'ADD_EMAIL_STARTED'; | |
export const ADD_EMAIL_FINISHED = 'ADD_EMAIL_FINISHED'; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment