The original example: Redux Form - Immutable JS Example
Last active
October 31, 2017 14:12
-
-
Save shinaisan/e7745b217be7692d9786f018aa0dc811 to your computer and use it in GitHub Desktop.
Redux Form - Immutable JS Example
This file contains hidden or 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 from 'react'; | |
import ImmutableForm from './ImmutableForm'; | |
import { createStore } from 'redux'; | |
import { Provider } from 'react-redux'; | |
import reducer from './reducer'; | |
import "bootstrap/dist/css/bootstrap.css"; | |
const store = createStore(reducer); | |
class App extends React.Component { | |
constructor(props) { | |
super(props); | |
this.state = {debug: ''}; | |
} | |
handleSubmit(values) { | |
const self = this; | |
self.setState({debug: JSON.stringify(values)}); | |
} | |
render() { | |
const onSubmit = this.handleSubmit.bind(this); | |
return ( | |
<Provider store={store}> | |
<div> | |
<ImmutableForm onSubmit={onSubmit} /> | |
<div> | |
<pre>{this.state.debug}</pre> | |
</div> | |
</div> | |
</Provider> | |
); | |
} | |
} | |
export default App; | |
This file contains hidden or 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
#!/bin/bash | |
NAME=redux-form-immutable-js | |
echo -n "This script runs create-react-app $NAME. Proceed? (Y/N) " | |
read YN | |
if [ x$YN != xY ] | |
then | |
echo "Bye." | |
exit | |
fi | |
# Delete this line only if you are sure what is done from this line on. | |
exit | |
create-react-app $NAME | |
cd $NAME | |
cp -v ../package.json . | |
cd src | |
rm -f App.* logo.svg | |
cp -v ../../*.js . | |
cd .. | |
yarn install | |
echo 'To launch the dev server, run `yarn run start`.' | |
This file contains hidden or 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 from 'react' | |
import { Field, reduxForm } from 'redux-form/immutable' // <--- immutable import | |
import validate from './validate' | |
import warn from './warn' | |
import { | |
Form, FormGroup, | |
Row, Col, | |
Button | |
} from 'react-bootstrap' | |
const renderField = ({ | |
input, | |
label, | |
type, | |
meta: { touched, error, warning } | |
}) => ( | |
<FormGroup> | |
<Row> | |
<Col sm={2}> | |
<label>{label}</label> | |
</Col> | |
<Col sm={8}> | |
<input {...input} type={type} placeholder={label} /> | |
{ | |
touched && | |
((error && <span>{error}</span>) || | |
(warning && <span>{warning}</span>)) | |
} | |
</Col> | |
</Row> | |
</FormGroup> | |
) | |
const ImmutableForm = props => { | |
const { handleSubmit, pristine, reset, submitting } = props | |
return ( | |
<Form onSubmit={handleSubmit}> | |
<Field | |
name="username" | |
type="text" | |
component={renderField} | |
label="Username" | |
/> | |
<Field name="email" type="email" component={renderField} label="Email" /> | |
<Field name="age" type="number" component={renderField} label="Age" /> | |
<div> | |
<Button type="submit" bsStyle="primary" | |
disabled={submitting}> | |
Submit | |
</Button> | |
<Button type="button" bsStyle="default" | |
disabled={pristine || submitting} onClick={reset}> | |
Clear Values | |
</Button> | |
</div> | |
</Form> | |
) | |
} | |
export default reduxForm({ | |
form: 'immutableExample', // a unique identifier for this form | |
validate, | |
warn | |
})(ImmutableForm) |
This file contains hidden or 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
const normalizePhone = value => { | |
if (!value) { | |
return value | |
} | |
const onlyNums = value.replace(/[^\d]/g, '') | |
if (onlyNums.length <= 3) { | |
return onlyNums | |
} | |
if (onlyNums.length <= 7) { | |
return `${onlyNums.slice(0, 3)}-${onlyNums.slice(3)}` | |
} | |
return `${onlyNums.slice(0, 3)}-${onlyNums.slice(3, 6)}-${onlyNums.slice( | |
6, | |
10 | |
)}` | |
} | |
export default normalizePhone |
This file contains hidden or 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
{ | |
"name": "redux-form-selecting-form-values", | |
"version": "0.1.0", | |
"private": true, | |
"dependencies": { | |
"bootstrap": "^3.3.7", | |
"immutable": "^3.8.2", | |
"react": "^16.0.0", | |
"react-bootstrap": "^0.31.5", | |
"react-dom": "^16.0.0", | |
"react-redux": "^5.0.6", | |
"redux": "^3.7.2", | |
"redux-form": "^7.1.2", | |
"redux-immutablejs": "^0.0.8" | |
}, | |
"devDependencies": { | |
"react-scripts": "1.0.14" | |
}, | |
"scripts": { | |
"start": "react-scripts start", | |
"build": "react-scripts build", | |
"test": "react-scripts test --env=jsdom", | |
"eject": "react-scripts eject" | |
} | |
} |
This file contains hidden or 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 { combineReducers } from 'redux'; | |
import { reducer as formReducer } from 'redux-form/immutable'; | |
const rootReducer = combineReducers({ | |
form: formReducer | |
}); | |
export default rootReducer; | |
This file contains hidden or 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 { SubmissionError } from 'redux-form' | |
const sleep = ms => new Promise(resolve => setTimeout(resolve, ms)) | |
function submit(values) { | |
return sleep(1000).then(() => { | |
// simulate server latency | |
if (!['john', 'paul', 'george', 'ringo'].includes(values.username)) { | |
throw new SubmissionError({ | |
username: 'User does not exist', | |
_error: 'Login failed!' | |
}) | |
} else if (values.password !== 'redux-form') { | |
throw new SubmissionError({ | |
password: 'Wrong password', | |
_error: 'Login failed!' | |
}) | |
} else { | |
return values; | |
} | |
}) | |
} | |
export default submit |
This file contains hidden or 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
const validate = values => { | |
// IMPORTANT: values is an Immutable.Map here! | |
const errors = {} | |
if (!values.get('username')) { | |
errors.username = 'Required' | |
} else if (values.get('username').length > 15) { | |
errors.username = 'Must be 15 characters or less' | |
} | |
if (!values.get('email')) { | |
errors.email = 'Required' | |
} else if ( | |
!/^[A-Z0-9._%+-]+@[A-Z0-9.-]+\.[A-Z]{2,4}$/i.test(values.get('email')) | |
) { | |
errors.email = 'Invalid email address' | |
} | |
if (!values.get('age')) { | |
errors.age = 'Required' | |
} else if (isNaN(Number(values.get('age')))) { | |
errors.age = 'Must be a number' | |
} else if (Number(values.get('age')) < 18) { | |
errors.age = 'Sorry, you must be at least 18 years old' | |
} | |
return errors | |
} | |
export default validate |
This file contains hidden or 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
const warn = values => { | |
// IMPORTANT: values is an Immutable.Map here! | |
const errors = {} | |
if (values.get('username') && /[^a-zA-Z0-9 ]/i.test(values.get('username'))) { | |
errors.username = 'Only alphanumeric characters' | |
} | |
if (values.get('email') && /.+@aol\.com/.test(values.get('email'))) { | |
errors.email = 'Really? You still use AOL for your email?' | |
} | |
if (values.get('age') && values.get('age') > 65) { | |
errors.age = 'You might be too old for this' | |
} | |
return errors | |
} | |
export default warn |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment