I try to set my values in my redux-form, but the input doesn't show the value. Can somebody please help me?
This is my code.
import React from "react";
import { Field, reduxForm } from "redux-form";
import {connect} from 'react-redux';
import {renderTextField, renderField, validate, warn} from "../../../Components/Forms/renders"
class SyncValidationForm extends React.Component {
constructor(props) {
super(props);
this.state = {
errors: {}
}
}
render() {
const { handleSubmit, pristine, reset, submitting } = this.props;
return (
<form onSubmit={handleSubmit}>
<div className="col-sm-12">
<h4 className="info-text"> Let's start with the basic details</h4>
</div>
<Field name="what.title.value" type="text" component={renderField} label="Titel" />
</form>
);
}
}
SyncValidationForm = reduxForm({
form: 'insertstart',
enableReinitialize: true,
validate, // <--- validation function given to redux-form
warn
})(SyncValidationForm);
const mapStateToProps = state => {
return {
initialValues: state.items.item,
}
}
export default connect(mapStateToProps)(SyncValidationForm)
I my console log I see this by console.log(this.props);
initialValues:{what.title.value: "test"}
You need to pass the initial values as an object, so instead of
what.title.value: "test"
your state.items.item should look like:
{ what: { title: { value: "test" } } }
See here for a working example.
Always use change function to bind data in redux-form fields
componentWillMount() {
const { change } = this.props
change('basicDetails', 'sdfuhdsuiafghfudsauifhdsuifhuiads') // this will bind name with basicDetails
}
<form onSubmit={handleSubmit}>
<div className="col-sm-12">
<h4 className="info-text"> Let's start with the basic details</h4>
</div>
<Field name="basicDetails" type="text" component={renderField} label="Titel" />
</form>
Related
i am using redux forms and redux to push form values into the store/state. First thing is, i get the state as undefined in form component when i pass it as props from container(INFORMATION COMPONENT) component which is not a React component class and finally use update function to update the store. I am new to React and the redux form is throwing me off
// App Component
class App extends Component {
constructor(props) {
super(props)
}
render() {
return (
<div className="App">
<InformationFrom state={this.props}/>
</div>
);
}
}
const mapStateToProps = (reduxState) => {
return reduxState;
}
const mapDispatchToProps = (dispatch) => {
return bindActionCreators(actionCreators, dispatch);
}
export default connect(
mapStateToProps, mapDispatchToProps
)(App)
// InformationForm Component
export default class InformationFrom extends React.Component {
render() {
return (
<div>
{console.log("infoForm props >> ", this.props)}
<SimpleForm/>
</div>
)
}
}
// Form stateless function component
const SimpleForm = props => {
const { handleSubmit, pristine, reset, submitting } = props
const state = this.props.state; // is undefined
return (
<div>
{ console.log("from state here >> ", this.props) }
<form onSubmit={handleSubmit(this.updateStore(values,state))} name="InformForm">
<div>
<div>
<Field name="firstName" component={renderInput} type="text" placeholder="First Name" label={"First Name"} />
<Field name="lastName" component={renderInput} type="text" placeholder="Last Name" label={"Last Name"} />
<Field name="email" component={renderInput} type="text" placeholder="Email" label={"Email"} />
</div>
</div>
<div style={style.normal}>
<button type="submit" disabled={submitting}>
Submit
</button>
<button type="button" disabled={submitting} onClick={reset}>
Clear Values
</button>
</div>
</form>
</div>
)
}
function updateStore(values, state){
let newStore = {};
newStore = {
}
return newStore;
}
const validate = values => {
const errors = {}
if (!values.firstName) {
errors.firstName = "Required!"
}
return errors;
}
const style = {
normal: {
margin: '10px'
}
}
export default reduxForm({
form: 'simple', // a unique identifier for this form
destroyOnUnmount: false,
validate
})(SimpleForm)
You are not pass props to SimpleForm in InformationFrom, so need to update
export default class InformationFrom extends React.Component {
render() {
return (
<div>
{console.log("infoForm props >> ", this.props)}
<SimpleForm/>
</div>
)
}
}
to
<SimpleForm {...this.props} />
and Export with connect to get state from redux
export default connect((state)=>state)( reduxForm({
form: 'simple', // a unique identifier for this form
destroyOnUnmount: false,
validate
})(SimpleForm) );
I have setup React-Redux form, but upon submit I am getting an empty object in the console.log()
Here is my code
import React from 'react';
import {reduxForm} from 'redux-form';
import {stockSave} from '../actions/actions';
class Stock extends React.Component {
customHandler(values){
console.log(values);
//this.props.stockSave(values);
}
render() {
const {fields: {id}, handleSubmit} = this.props;
return (
<form onSubmit={handleSubmit(this.customHandler)}>
<input type="text" {...id} />
<button type="submit">Submit</button>
</form>
)
}
};
export default reduxForm({
form: 'myForm',
fields: ['id']
}, null, {stockSave})(Stock);
After submitting the form, I get empty object in the console. Here is the screenshot https://www.screencast.com/t/lzNoKPwsLU
Any help regarding this problem? Thanks!
You need to add a constructor in your class and bind your customHandler function.
class Stock extends React.Component {
constructor(props) {
super(props);
this.customHandler = this.customHandler.bind(this);
}
customHandler(values){
console.log(values);
//this.props.stockSave(values);
}
render() {
const {fields: {id}, handleSubmit} = this.props;
return (
<form onSubmit={handleSubmit(this.customHandler)}>
<input type="text" {...id} />
<button type="submit">Submit</button>
</form>
)
}
};
export default reduxForm({
form: 'myForm',
fields: ['id']
}, null, {stockSave})(Stock);
And why are calling handleSubmit from pros and passing your customHandle as parameter?
I think that you want to call your handleSubmit this would be better:
customHandler(values){
this.props.handleSubmit();
console.log(values);
//this.props.stockSave(values);
}
I am using react/redux with redux-form and for some reason the input values are not showing on my edit form.
I console.log my post and it shows that they are there, but for some reason it is not working. I will post code below.
edit component:
import React , { Component } from 'react';
import * as actions from '../../actions/posts_actions';
import { reduxForm, Field } from 'redux-form';
import {connect} from 'react-redux';
import {Link} from 'react-router-dom';
class EditPost extends Component {
componentDidMount() {
const {id} = this.props.match.params;
this.props.getOnePost(id);
}
renderField(field) {
const { meta: {touched, error} } = field;
const className = `form-group ${touched && error ? 'has-danger' : ''}`;
return (
<div className={className}>
<label><strong>{field.label}:</strong></label>
<input
className="form-control"
type={field.type}
value={field.value}
{...field.input}
/>
<div className="text-help">
{ touched ? error : ''}
</div>
</div>
)
}
onSubmit(values) {
const {id} = this.props.match.params;
this.props.updatePost(values, id, () => {
this.props.history.push(`/posts/${id}`);
});
}
render() {
const {handleSubmit} = this.props;
const {post} = this.props;
if(!post) {
return <div> Loading... </div>;
}
console.log(post);
return (
<form onSubmit={handleSubmit(this.onSubmit.bind(this))}>
<Field
label="Title"
name="title"
type="text"
value={post.title}
component={this.renderField}
/>
<Field
label="Content"
name="content"
type="text"
value={post.content}
component={this.renderField}
/>
<button type="submit" className="btn btn-success">Submit</button>
<Link to={`/posts/${post._id}`} className="btn btn-danger">Cancel</Link>
</form>
);
}
}
function validate(values) {
const errors = {};
if(!values.title) {
errors.title = "Enter a title!";
}
if(!values.content) {
errors.content = "Enter some content please!";
}
return errors;
}
function mapStateToProps({ posts }, ownProps) {
return { post: posts[ownProps.match.params.id] };
}
export default reduxForm({
validate,
form: 'editform'
})(connect(mapStateToProps, actions)(EditPost));
Instead of setting the value directly, pass an initialValues prop:
function mapStateToProps({ posts }, ownProps) {
const post = posts[ownProps.match.params.id]
return {
post,
initialValues: {
...post
}
};
}
remove value props from Fields in your form. So long as the properties on your Post object are the same as the name of the field you want to populate, you can just use object spread. If they are different, you'll have to map them appropriately
initialValues: {
contentField: post.content
}
<Field name="contentField" />
initial values have to be set before you use the reduxForm enhancer. Also, because I know it'll come up (and trust me, it always comes up eventually), if you want your form values to update if your model updates, you'll have add enableReinitialize: true to reduxForm's config
I'm creating a basic portfolio website, that has a Contact form section, where people can send me a message to my email via Formspree. I'm using Redux Forms for this and the form works, but I'd like to reset the form fields and add some kind of 'success' message on successful submit.
I've tried 2 methods: 1) calling this.props.resetForm() and 2) calling dispatch(reset('ContactForm'). Neither have worked.
Here is the code:
contact.js:
import React, { Component } from 'react';
import { connect } from 'react-redux';
import { Field, reduxForm } from 'redux-form';
import { sendMail } from '../actions';
class Contact extends Component {
renderField(field) {
const { meta: { touched, error } } = field;
const className = `form-group ${touched && error && 'has-error'}`;
return (
<div className={className}>
<label>{field.label}</label>
{field.type == 'text' ?
<input
className='form-control'
type={field.type}
{...field.input}
/> :
<textarea
className='form-control'
rows='5'
{...field.input}
/>}
<div className='help-block'>
{touched && error}
</div>
</div>
);
}
onSubmit(values) {
this.props.sendMail(values, () => {
this.props.resetForm();
});
}
render() {
const { handleSubmit } = this.props;
return (
<div id='contact'>
<h1>Contact</h1>
<p>Feel free to drop me a mail. Whether it's work-related or about coding, tech, entrepreneurship, travel, football or life in general. I'm always looking to connect with other people.</p>
<div id='contact-form'>
<form onSubmit={handleSubmit(this.onSubmit.bind(this))}>
<Field
label='Name:'
name='name'
type='text'
component={this.renderField}
/>
<Field
label='Email:'
name='email'
type='text'
component={this.renderField}
/>
<Field
label='Message:'
name='message'
type='textarea'
component={this.renderField}
/>
<button
type='submit'
className='btn btn-primary'
>
Submit
</button>
</form>
</div>
</div>
);
}
}
function validate(values) {
const errors = {};
if (!values.name) {
errors.name = "Enter a name"
}
if (!values.email) {
errors.email = "Enter an email"
}
if (!values.message) {
errors.message = "Enter a message"
}
return errors;
}
export default reduxForm({
form: 'ContactForm',
validate
})(
connect(null, { sendMail })(Contact)
);
actions/index.js:
import axios from 'axios';
import { reset } from 'redux-form';
export const MAIL_SENT = 'MAIL_SENT';
const ROOT_URL='https://formspree.io/'
const EMAIL = 'xxxxxx#gmail.com'
export function sendMail(values) {
const request = axios.post(`${ROOT_URL}${EMAIL}`, values);
return {
type: MAIL_SENT,
payload: true
};
dispatch(reset('ContactForm'));
}
You need to add a constructor to the class contact.
class Contact extends Component {
constructor(props) {
super(props);
}
...
};
Putting dispatch(reset('ContactForm')) after return syntax, it would never get called. By the way, the action creator is supposed to be a pure function. Adding dispatch action to it is not a good idea.
Hope this help.
Use
this.props.reset()
Using this works on resetting the form after submit.
I have a field (source-file) in redux-form which is being updated by a change in the application state. The state value is being properly delivered to the field but when clicking submit, only the first field (name) is submitted (which I fill in interactively).
What am I doing wrong here?
import React, { Component, PropTypes } from 'react';
import { reduxForm, Field } from 'redux-form';
import { connect } from 'react-redux';
import { Link } from 'react-router';
import * as actions from '../../actions/job_actions';
import UploadPage from './upload_page';
const renderField = field => (
<div>
<label>{field.input.label}</label>
<input {...field.input}/>
{field.touched && field.error && <div className="error">{field.error}</div>}
</div> );
class JobForm extends Component {
handleFormSubmit(formProps) {
this.props.createJob(formProps); }
render() {
const { handleSubmit } = this.props;
return (
<div>
<form onSubmit={handleSubmit(this.handleFormSubmit.bind(this))}>
<label>Title</label>
<Field name="name" component={renderField} type="text" />
<label>Input File</label>
<Field name="source_file" component={() => {
return (
<div class="input-row">
<input type="text" value={this.props.uploadedFile} />
</div>
)
}} />
<button type="submit" className="btn btn-
primary">Submit</button>
</form>
</div>
);
};
}
const form = reduxForm({ form: 'JobForm' });
function mapStateToProps({uploadedFile}) { return { uploadedFile }; }
export default connect(mapStateToProps, actions)(form(JobForm));
If you want redux-form to include your field, then you'll need to render it as an actual field (as you do with your renderField).
If you don't want to treat it as an actual field, then the redux-form author suggests injecting the values from state within your submit handler. Maybe something like this:
handleFormSubmit(formProps) {
this.props.createJob({ ...formProps, source_file: this.props.uploadedFile} );
}