Monday, May 20, 2024
 Popular · Latest · Hot · Upcoming
60
rated 0 times [  61] [ 1]  / answers: 1 / hits: 44586  / 9 Years ago, tue, october 20, 2015, 12:00:00

I got one form who is used to Create, Read, Update and Delete. I created 3 components with the same form but I pass them different props. I got CreateForm.js, ViewForm.js (readonly with the delete button) and UpdateForm.js.



I used to work with PHP, so I always did these in one form.



I use React and Redux to manage the store.



When I'm in the CreateForm component, I pass to my sub-components this props createForm={true} to not fill the inputs with a value and don't disable them. In my ViewForm component, I pass this props readonly=readonly.



And I got another problem with a textarea who is filled with a value and is not updatable. React textarea with value is readonly but need to be updated



What's the best structure to have only one component which handles these different states of the form?



Do you have any advice, tutorials, videos, demos to share?


More From » reactjs

 Answers
5

I found the Redux Form package. It does a really good job!



So, you can use Redux with React-Redux.



First you have to create a form component (obviously):



import React from 'react';
import { reduxForm } from 'redux-form';
import validateContact from '../utils/validateContact';

class ContactForm extends React.Component {
render() {
const { fields: {name, address, phone}, handleSubmit } = this.props;
return (
<form onSubmit={handleSubmit}>
<label>Name</label>
<input type=text {...name}/>
{name.error && name.touched && <div>{name.error}</div>}

<label>Address</label>
<input type=text {...address} />
{address.error && address.touched && <div>{address.error}</div>}

<label>Phone</label>
<input type=text {...phone}/>
{phone.error && phone.touched && <div>{phone.error}</div>}

<button onClick={handleSubmit}>Submit</button>
</form>
);
}
}

ContactForm = reduxForm({
form: 'contact', // the name of your form and the key to
// where your form's state will be mounted
fields: ['name', 'address', 'phone'], // a list of all your fields in your form
validate: validateContact // a synchronous validation function
})(ContactForm);

export default ContactForm;


After this, you connect the component which handles the form:



import React from 'react';
import { connect } from 'react-redux';
import { initialize } from 'redux-form';
import ContactForm from './ContactForm.react';

class App extends React.Component {

handleSubmit(data) {
console.log('Submission received!', data);
this.props.dispatch(initialize('contact', {})); // clear form
}

render() {
return (
<div id=app>
<h1>App</h1>
<ContactForm onSubmit={this.handleSubmit.bind(this)}/>
</div>
);
}

}

export default connect()(App);


And add the redux-form reducer in your combined reducers:



import { combineReducers } from 'redux';
import { appReducer } from './app-reducers';
import { reducer as formReducer } from 'redux-form';

let reducers = combineReducers({
appReducer, form: formReducer // this is the form reducer
});

export default reducers;


And the validator module looks like this:



export default function validateContact(data, props) {
const errors = {};
if(!data.name) {
errors.name = 'Required';
}
if(data.address && data.address.length > 50) {
errors.address = 'Must be fewer than 50 characters';
}
if(!data.phone) {
errors.phone = 'Required';
} else if(!/d{3}-d{3}-d{4}/.test(data.phone)) {
errors.phone = 'Phone must match the form 999-999-9999'
}
return errors;
}


After the form is completed, when you want to fill all the fields with some values, you can use the initialize function:



componentWillMount() {
this.props.dispatch(initialize('contact', {
name: 'test'
}, ['name', 'address', 'phone']));
}


Another way to populate the forms is to set the initialValues.



ContactForm = reduxForm({
form: 'contact', // the name of your form and the key to
fields: ['name', 'address', 'phone'], // a list of all your fields in your form
validate: validateContact // a synchronous validation function
}, state => ({
initialValues: {
name: state.user.name,
address: state.user.address,
phone: state.user.phone,
},
}))(ContactForm);


If you got any other way to handle this, just leave a message! Thank you.


[#64673] Saturday, October 17, 2015, 9 Years  [reply] [flag answer]
Only authorized users can answer the question. Please sign in first, or register a free account.
jocelynkarsynr

Total Points: 472
Total Questions: 98
Total Answers: 96

Location: Macau
Member since Mon, Nov 16, 2020
4 Years ago
jocelynkarsynr questions
Tue, Feb 8, 22, 00:00, 2 Years ago
Sat, Jul 11, 20, 00:00, 4 Years ago
Sun, May 10, 20, 00:00, 4 Years ago
Sat, Jan 18, 20, 00:00, 4 Years ago
;