I have components for dropdown. I try to generate a dynamic dropdown using json data. But I can't do it. I share my following code of the components. I am new in react.
1st component:
import React, {Component} from 'react';
import PropTypes from "prop-types";
const DropDownInput = props =>(
<option
value={props.value}
label={props.name}
/>
)
DropDownInput.PropTypes ={
label: PropTypes.array.isRequired,
value: PropTypes.array.isRequired,
}
DropDownInput.defaultProps={
option:'Select',
}
export default DropDownInput;
2nd component:
import React, {Component} from 'react';
import PropTypes from "prop-types";
import DropDownInput from "./DropDownInput";
const SelectDropDown = props => {
return(
<select className="form-select" aria-label="Default select example">
<DropDownInput
value={props.value}
name={props.name}
/>
</select>
)
};
SelectDropDown.propTypes = {
value: PropTypes.array.isRequired,
name: PropTypes.array.isRequired,
}
export default SelectDropDown;
3rd component:
import React, {Component} from 'react';
import {Button} from "react-bootstrap";
import PropTypes from "prop-types";
import TextInput from "./text-input";
import CheckedInput from "./checked-input";
import SelectDropDown from "./SelectDropDown";
const SubCategorySubmitForm = props => {
return(
<form onSubmit={props.submitHandler}>
<SelectDropDown value={props.OptionValue} name={props.label}/>
<TextInput
name="subCategory"
label="Enter Sub Category"
placeholder="Enter Sub Category"
value={props.values.subCategory}
onChange={props.changeHandler}
/>
<TextInput
name="userid"
label="Enter User Id"
placeholder="User Id Enter"
value={props.values.userid}
// error={props.errors.userid}
onChange={props.changeHandler}
/>
<CheckedInput
styleName="mt-2"
checkBoxClassName="mx-2"
label="All Information is Correct"
name="isAgreement"
value={props.values.isAgreement}
checked= {props.isAgreement}
onChange={props.handlerAgreement}
/>
<Button
variant="primary"
type="submit"
disabled={!props.isAgreement}
>
Submit
</Button>
</form>
)
};
SubCategorySubmitForm.propTypes = {
values: PropTypes.object.isRequired,
label: PropTypes.array.isRequired,
changeHandler: PropTypes.func.isRequired,
submitHandler: PropTypes.func.isRequired,
handlerAgreement: PropTypes.func.isRequired,
isAgreement: PropTypes.bool.isRequired,
OptionValue: PropTypes.array.isRequired,
//errors: PropTypes.object.isRequired,
}
export default SubCategorySubmitForm;
I have json data to generate the dropdown.
Last component:
import React, {Component, Fragment} from 'react';
import {Card, Col, Container, Dropdown, Row} from "react-bootstrap";
import FormUp from "./fillup-form";
import Axios from "axios";
import DemoModal from "./DemoModal";
import {MdOutlineEditCalendar} from "react-icons/md";
import DropDownInput from "./DropDownInput";
import SubCategoryFormFillUp from "./SubCategoryFormFillUp";
import SubCategorySubmitForm from "./SubCategoryFormFillUp";
const FormValues={
subCategory: '',
userid: '',
}
class SubCategoryForm extends Component {
state ={
values: FormValues,
DataList:[],
isLoading:true,
isError:false,
isAgreement: true,
}
componentDidMount() {
Axios.get("/getMainCategoryByName").then((response)=>{
if(response.status==200){
this.setState({
DataList:response.data,
isLoading: false,
});
console.log(response.data)
}
else {
this.setState({isLoading: false, isError:true})
}
}).catch((error)=>{
this.setState({isLoading: false, isError:true})
})
}
changeHandler = event =>{
this.setState(
{values :{
... this.state.values,
[event.target.name]: event.target.value
}}
)};
handlerAgreement = event =>{
this.setState({
isAgreement: event.target.checked,
}
)
console.log('ss');
};
submitHandler=(e)=>{
e.preventDefault();
}
render() {
const myList= this.state.DataList;
const myView=myList.map(myList=>{
return(<DropDownInput
value={myList.id}
name={myList.main_category_name}
/>);
})
return (
<Fragment>
<Container fluid className="mt-5">
<Row>
<Col sm={2}>
</Col>
<Col sm={4}>
{Array.from({ length: 1 }).map((_, idx) => (
<Col>
<Card>
<Card.Body>
<Card.Title><u>Main Category Setup</u></Card.Title>
<select className="form-select" aria-label="Default select example">
{myView}
</select>
<SubCategorySubmitForm
values = {this.state.values}
changeHandler={this.changeHandler}
submitHandler={this.submitHandler}
handlerAgreement={this.handlerAgreement}
isAgreement={this.state.isAgreement}
// OptionValue={myList.map(myList=>{myList.id})}
OptionValue={myList.map(myList=>{myList.id})}
label={myList.map(myList=>{myList.main_category_name})}
/>
</Card.Body>
</Card>
</Col>
))}
</Col>
<Col sm={6}>
</Col>
</Row>
</Container>
</Fragment>
);
}
}
export default SubCategoryForm;
How to write the code to generate the dropdown with json data in my last component.
Related
I was trying to build simple react-redux app using reducers. But every time I open the website it is popping up this error and I couldn't open the console. I tried to clean cookies and caches but no help.
Whenever I change <Posts /> and <Form /> to simple <h1> tags it works perfectly fine, but I can't find the bug.
My code in
index.js:
import React from 'react';
import ReactDOM from 'react-dom';
import { Provider } from 'react-redux';
import { createStore, applyMiddleware, compose } from 'redux';
import thunk from 'redux-thunk';
import { reducers } from './reducers/index.js';
import App from './App';
const store = createStore(reducers, compose(applyMiddleware(thunk)));
ReactDOM.render(
<Provider store={store}>
<App />
</Provider>,
document.getElementById('root'),
);
App.js
import React,{ useEffect, useState } from 'react';
import { Container, AppBar, Typography, Grid, Grow } from '#material-ui/core';
import { useDispatch } from 'react-redux';
import Posts from '../src/components/Posts';
import Form from './components/form';
import { getPosts } from './actions/action';
function App() {
const [currentId, setCurrentId] = useState();
const dispatch = useDispatch();
useEffect(() =>{
dispatch(getPosts());
},[dispatch, currentId]);
return (
<div>
<Container maxWidth='lg'>
<AppBar position='static' color='inherit'>
<Typography variant='h2' align='center' >SimplePRATICE</Typography>
</AppBar>
<Grow in>
<Container>
<Grid container justify='space-between' alignItems='stretch' spacing={3}>
<Grid item xs={12} sm={4}>
<Form currentId={currentId} setCurrentId={setCurrentId} />
</Grid>
</Grid>
</Container>
</Grow>
</Container>
</div>
);
}
export default App;
form.js
import React, { useEffect, useState } from 'react';
import { Paper, Button, TextField, Typography } from '#material-ui/core';
import { useSelector, useDispatch } from 'react-redux';
import { createPost, updatePost } from '../actions/action.js';
function Form({ currentId, setCurrentId }) {
const [postData, setpostData] = useState({ name:'', message:'' });
const post = useSelector((state) => (currentId ? state.posts.find((message) => message._id === currentId ) :null ));
const dispatch = useDispatch();
useEffect(() => {
if (post) setpostData(post);
}, [post]);
const clear = () =>{
setCurrentId(0);
setpostData({ name: '', message:''});
};
const handleSubmit = async (e) => {
e.preventDefault();
if (currentId === 0){
dispatch(createPost(postData));
}else{
dispatch(updatePost(currentId, postData));
}
clear();
};
return (
<Paper>
<Form onSubmit={handleSubmit}>
<Typography>Creating Post</Typography>
<TextField name="name" variant="outlined" label="Name" fullWidth value={postData.name} onChange={(e) => setpostData({ ...postData, name: e.target.value })} />
<TextField name="message" variant="outlined" label="Message" fullWidth multiline rows={4} value={postData.message} onChange={(e) => setpostData({ ...postData, message: e.target.value })} />
<Button varient='contained' color='primary' size='large' type='submit' fullWidth>Submit</Button>
</Form>
</Paper>
)
}
export default Form
Posts.js
import React from 'react';
import Post from './post.js';
import { Grid } from '#material-ui/core';
import { useSelector } from 'react-redux';
function Posts({ setCurrentId }) {
const posts = useSelector((state) => state.posts);
return (
<Grid container alignItems='stretch' spacing={3}>
{posts.map((post) => (
<Grid key={post._id} item xs={12} sm={6} md={6}>
<Post post={post} setCurrentId={setCurrentId} />
</Grid>
))}
</Grid>
)
}
export default Posts
Post.js
import React from 'react';
import { Card, CardActions, CardContent, Button, Typography } from '#material-ui/core/';
import DeleteIcon from '#material-ui/icons/Delete';
import MoreHorizIcon from '#material-ui/icons/MoreHoriz';
import { useDispatch } from 'react-redux';
import { deletePost } from '../actions/action.js';
function Post({ post, setCurrentId }) {
const dispatch = useDispatch();
return (
<Card>
<div>
<Typography varient='h6'>{post.name}</Typography>
</div>
<di>
<Button style={{ color:'white' }} size='small' onClick={()=> setCurrentId(post._id)}><MoreHorizIcon fontSize='default' /></Button>
</di>
<CardContent>
<Typography vaarient='body2' color='textSecondary' component='p'>{post.message}</Typography>
</CardContent>
<CardActions>
<Button size='small' color='primary' onClick={()=> dispatch(deletePost(post._id))} ><DeleteIcon fontSize='small'>Delete</DeleteIcon></Button>
</CardActions>
</Card>
)
}
export default Post
import axios from 'axios';
const url = 'http://localhost:5000/posts';
export const fetchPosts = () => axios.get(url);
export const createPost = (newPost) => axios.post(url, newPost);
export const updatePost = (id, updatedPost) => axios.patch(`${url}/${id}`, updatedPost);
export const deletePost = (id) => axios.delete(`${url}/${id}`);
Your Form component renders itself:
return (
<Paper>
<Form onSubmit={handleSubmit}>
<Typography>Creating Post</Typography>
<TextField name="name" variant="outlined" label="Name" fullWidth value={postData.name} onChange={(e) => setpostData({ ...postData, name: e.target.value })} />
<TextField name="message" variant="outlined" label="Message" fullWidth multiline rows={4} value={postData.message} onChange={(e) => setpostData({ ...postData, message: e.target.value })} />
<Button varient='contained' color='primary' size='large' type='submit' fullWidth>Submit</Button>
</Form>
</Paper>
)
I think you meant <form> which is not a react component.
return (
<Paper>
<form onSubmit={handleSubmit}>
<Typography>Creating Post</Typography>
<TextField name="name" variant="outlined" label="Name" fullWidth value={postData.name} onChange={(e) => setpostData({ ...postData, name: e.target.value })} />
<TextField name="message" variant="outlined" label="Message" fullWidth multiline rows={4} value={postData.message} onChange={(e) => setpostData({ ...postData, message: e.target.value })} />
<Button varient='contained' color='primary' size='large' type='submit' fullWidth>Submit</Button>
</form>
</Paper>
)
You must have selected a wrong element in your html which is not going on well with the code.
Hence please check all the elements properly.
If it is a functional component , check it again.
I had the same issue and it got resolved.
I couldn't find any solution in any other questions similar to mine so I decided to ask you for help.
I have tests to my <Login/> page:
import React from 'react';
import { render } from '../../__test__/utils';
import Login from '.';
test('Renders the Login page', () => {
const { getByTestId } = render(<Login />);
expect(getByTestId('login-page')).toBeInTheDocument(); //WORKS
});
test('Renders disabled submit button by default', () => {
const { getByTestId } = render(<Login />);
expect(getByTestId('login-button')).toHaveAttribute('disabled'); // ERROR HERE
});
test('should match base snapshot', () => {
const { asFragment } = render(<Login />);
expect(asFragment()).toMatchSnapshot(); //WORKS
});
I am using the 'utils.js' in my tests because I want to wrap every testing component in the providers I am using. Here is how the utils file looks like:
import React, { useState } from 'react';
import { render as rtlRender } from '#testing-library/react';
import '#testing-library/jest-dom/extend-expect';
import { renderRoutes } from 'react-router-config';
import { Router } from 'react-router-dom';
import { createStore } from 'redux';
import { Provider } from 'react-redux';
import { ThemeProvider } from '#material-ui/styles';
import { createMemoryHistory } from 'history';
import StylesProvider from '../components/StylesProvider';
import routes from '../routes';
import reducer from '../reducers';
import { theme } from '../theme';
const history = createMemoryHistory();
const render = (
ui,
{ initialState, store = createStore(reducer, initialState), ...renderOptions } = {}
) => {
const Wrapper = ({ children }) => {
const [direction] = useState('ltr');
return (
<Provider store={store}>
<ThemeProvider theme={theme}>
<StylesProvider direction={direction}>
<Router history={history}>
{children}
{renderRoutes(routes)}
</Router>
</StylesProvider>
</ThemeProvider>
</Provider>
);
};
return rtlRender(ui, { wrapper: Wrapper, ...renderOptions });
};
export * from '#testing-library/react';
export { render };
Unfortunately, I cannot show the whole app code so I'll make it short. The <Login /> component looks like below:
import React from 'react';
import { makeStyles } from '#material-ui/styles';
import {
Card, CardContent, CardHeader, Typography, Divider, Grid
} from '#material-ui/core';
import Page from 'src/components/Page';
import LoginForm from './LoginForm';
const Login = () => (
<Page className={classes.root} title="Login" dataTestId="login-page">
//here the component body//
<LoginForm
afterLoginRoute="/overview"
loginEndpoint="login"
userRole={userRoles.USER}
className={classes.loginForm}
/>
</Page>
)
In the <LoginForm /> component I have a Material-UI button with data-testid="login-button"
LoginForm:
return (
<div>
<Snackbar open={loginStatus.error} autoHideDuration={6000}>
<Alert severity="error">
Se ha producido un error, comprueba los credenciales y prueba de nuevo.
</Alert>
</Snackbar>
<form {...rest} className={clsx(classes.root, className)} onSubmit={handleSubmit}>
<div className={classes.fields}>
<TextField
className={classes.input}
error={hasError('email')}
fullWidth
helperText={hasError('email') ? formState.errors.email[0] : null}
label="Email"
name="email"
onChange={handleChange}
value={formState.values.email || ''}
variant="outlined"
/>
<TextField
className={classes.input}
error={hasError('password')}
fullWidth
helperText={hasError('password') ? formState.errors.password[0] : null}
label="ContraseƱa"
name="password"
onChange={handleChange}
type="password"
value={formState.values.password || ''}
variant="outlined"
/>
</div>
<Button
className={classes.submitButton}
color="secondary"
disabled={!formState.isValid}
size="large"
type="submit"
variant="contained"
data-testid="login-button"
>
Entrar
</Button>
</form>
</div>
);
Current test result I have is TestingLibraryElementError: Found multiple elements by: [data-testid="login-button"]. I am out of ideas right now. Could this happen because I try to pass the data-testid prop to the <Button /> which is imported from Material-UI library? Then, shouldn't I see other error message? Please help.
I'm trying to apply styles to my React form. I'm using withStytles from Material UI.
The styles however are not taking into affect. I tried testing the code in my first <DialogContentText> in the code below, but it's not working.
EDIT: edited my code to reflect David's answer.
import React, { Component, Fragment } from 'react';
import { withStyles } from '#material-ui/core/styles';
import Button from '#material-ui/core/Button';
import Dialog from '#material-ui/core/Dialog';
import DialogActions from '#material-ui/core/DialogActions';
import DialogContent from '#material-ui/core/DialogContent';
import DialogContentText from '#material-ui/core/DialogContentText';
import DialogTitle from '#material-ui/core/DialogTitle';
import IconButton from '#material-ui/core/IconButton';
import AddCircleIcon from '#material-ui/icons/AddCircle';
import TextField from '#material-ui/core/TextField';
import FormHelperText from '#material-ui/core/FormHelperText';
import Select from '#material-ui/core/Select';
import MenuItem from '#material-ui/core/MenuItem';
import InputLabel from '#material-ui/core/InputLabel';
import FormControl from '#material-ui/core/FormControl';
const styles = theme => ({
formControl: {
width: 500
},
selectEmpty: {
marginTop: theme.spacing(2),
},});
export default class extends Component {
state = {
open: false,
bucket: {
name:'',
category: '',
about: '',
}
}
handleToggle = () => {
this.setState({
open: !this.state.open
})
}
handleChange = name => ({ target: { value } }) => {
this.setState({
bucket:{
...this.state.bucket,
[name]: value,
}
})
}
render() {
const { open, bucket: { name, category, about } } = this.state;
const { classes } = this.props;
return <Fragment>
<IconButton color="primary" size="large" onClick={this.handleToggle}>
<AddCircleIcon/>
</IconButton>
<Dialog open={open} onClose={this.handleToggle} aria-labelledby="form-dialog-title">
<DialogTitle id="form-dialog-title">Create your Bucket</DialogTitle>
<DialogContent>
<DialogContentText>
Get started! Make your bucket by telling us a little bit more.
</DialogContentText>
<form>
<TextField
id="filled-password-input"
label="Bucket Title"
value={name}
variant="filled"
onChange={this.handleChange('name')}
margin="normal"
required = "true"
className = {classes.formControl}
/>
<br/>
<br/>
<FormControl>
<InputLabel htmlFor="category"> What type of Bucket </InputLabel>
<Select
labelId="demo-simple-select-helper-label"
id="demo-simple-select-helper"
value={category}
onChange={this.handleChange('category')}
required = "true"
>
<MenuItem value={'personal'}> Personal </MenuItem>
<MenuItem value={'social'}> Social </MenuItem>
</Select>
</FormControl>
<FormHelperText>Is this your personal or social Bucket?</FormHelperText>
<TextField
id="filled-password-input"
label="About"
multiline
rows="5"
value={about}
variant="filled"
onChange={this.handleChange('about')}
margin="normal"
/>
<FormHelperText>Will this be your tech stock watchlist?</FormHelperText>
<br/>
<br/>
</form>
</DialogContent>
<DialogActions>
<Button
color="primary"
variant="raised"
onClick={this.handleSubmit}
>
Create Bucket
</Button>
</DialogActions>
</Dialog>
</Fragment>
}
}
export withStyles(styles)(YourComponent);
How would I be able to apply these styles to my code below? Thank you for assistance.
TL;DR: You are trying to use a React Hook const classes = useStyles; within a class component. Also, useStyles is a function, not an object.
NL;PR: Hooks only work on functional components (useStyles() hooks are obtained via makeStyles() instead of withStyles()). You apply HOC withStyles(YourComponent) to your class component not your styles, so you can access const {classes, ...rest} = this.props; in the render() method.
It should look like this:
const styles = theme => ({
formControl: {
width: 500
},
selectEmpty: {
marginTop: theme.spacing(2),
},});
class YourComponent extends PureComponent {
//...
render(){
const {classes, ...rest} = this.props;
// now your can access classes.formControl ...
}
}
export withStyles(styles)(YourComponent);
My custom component has onChange event, which is working pretty good, but when I tried onSubmit, It does not work.
Alert does not display.
Currently my data provider get all values from inputs except my custom component, what should I do?
what's wrong with the code?
It's possible to pass data from this custom component to the parrent form?
Parrent form:
export const smthEdit = props => (
<Edit {...props} title={<smthTitle/>} aside={<Aside />}>
<SimpleForm>
<DisabledInput source="Id" />
<TextInput source="Name" />
<ReferrenceSelectBox label="Socket" source="SocketTypeId" reference="CPUSocketType"></ReferrenceSelectBox>
<DateField source="CreatedDate" showTime
locales={process.env.REACT_APP_LOCALE}
disabled={true} />
</SimpleForm>
</Edit>
);
My custom component (ReferrenceSelectBox):
handleSubmit(event) {
alert('smth');
}
render() {
return (
<div style={divStyle}>
<FormControl onSubmit={this.handleSubmit}>
<InputLabel htmlFor={this.props.label}>{this.props.label}</InputLabel>
<Select
multiple
style={inputStyle}
value={this.state.selectedValue}
onChange={this.handleChange}
>
{this.renderSelectOptions()}
</Select>
</FormControl>
</div>
);
}
Error is change FormControl to form
<form onSubmit={(event) => this.handleSubmit(event)}>
<InputLabel htmlFor={this.props.label}>{this.props.label}</InputLabel>
<Select
multiple
style={inputStyle}
value={this.state.selectedValue}
onChange={this.handleChange}
>
{this.renderSelectOptions()}
</Select>
</form>
Form Input.js
import React, { Component } from 'react';
import { Edit, SimpleForm, TextInput } from 'react-admin';
import SaveUpdate from './button/saveupdate.js';
export default class MemberDetail extends Component {
render(){
return (
<Edit title={"Member Detail"} {...this.props} >
<SimpleForm redirect={false} toolbar={<SaveUpdate changepage={changepage}>
<TextInput source="name" label="name"/>
</SimpleForm>
</Edit>)
}
}
/button/saveupdate.js
import React, { Component } from 'react';
import { Toolbar, UPDATE, showNotification, withDataProvider, GET_ONE} from 'react-admin';
import Button from '#material-ui/core/Button';
class SaveUpdate extends Component {
doSaveUpdate = (data) => {
const { dataProvider, dispatch } = this.props
dataProvider(UPDATE, endPoint, { id: data.id, data: { ...data, is_approved: true } })
.then((res) => {
dispatch(showNotification('Succes'));
})
.catch((e) => {
console.log(e)
dispatch(showNotification('Fail', 'warning'))
})
}
render(){
return (
<Toolbar {...this.props}>
<Button variant='contained' onClick={handleSubmit(data => { this.doSaveUpdate(data) })}>
SAVE
</Button>
</Toolbar>
)
}
export default withDataProvider(SaveUpdate);
This handlesubmit extra withDataProvider
I have a redux-form component that I correctly passing in the initial form state values but when I click inside the form I cannot edit the values. I am have followed all the documentation like the following link:
Initialize From State
And I also followed the documentation to implement a custom input:
Will redux-form work with a my custom input component?
So I am trying to figure out what am I missing? Here is my form component:
EditJournalForm.jsx
import "./styles/list-item.scss";
import {Button, ButtonToolbar} from "react-bootstrap";
import {connect} from "react-redux";
import {Field, reduxForm} from "redux-form";
import InputField from "../form-fields/InputField";
import PropTypes from "prop-types";
import React from "react";
class EditJournalForm extends React.Component {
render() {
//console.log('EditJournalForm this.props', this.props);
const {closeOverlay, handleSubmit, initialValues, pristine, submitting,} = this.props;
return (
<form onSubmit={handleSubmit}>
<div>
<div className="form-field">
<Field
component={props =>
<InputField
content={{val: initialValues.title}}
updateFn={param => props.onChange(param.val)}
{...props}
/>
}
label="Journal title"
name="title"
type="text"
/>
</div>
<div className="form-field">
<Field
component={props =>
<InputField
content={{val: initialValues.description}}
updateFn={param => props.onChange(param.val)}
{...props}
/>
}
componentClass="textarea"
label="Description"
name="description"
rows="5"
type="text"
/>
</div>
<div className="form-button-group">
<ButtonToolbar>
<Button
bsSize="small"
style={{"width": "48%"}}
onClick={() => {
if (closeOverlay) {
closeOverlay();
}
}}
>
Cancel
</Button>
<Button
bsSize="small"
disabled={pristine || submitting}
style={
{
"backgroundColor": "#999",
"width": "48%"
}}
type="submit"
>
Add
</Button>
</ButtonToolbar>
</div>
</div>
</form>
);
}
}
EditJournalForm.propTypes = {
"closeOverlay": PropTypes.func,
"handleSubmit": PropTypes.func.isRequired,
"pristine": PropTypes.bool.isRequired,
"submitting": PropTypes.bool.isRequired,
"initialValues": PropTypes.object
};
EditJournalForm.defaultProps = {
"closeOverlay": undefined
};
export default reduxForm({
form: "editJournal",
enableReinitialize: true
})(connect((state, ownProps) => {
return {
initialValues: {
"title": state.bees.entities.journals[ownProps.journal.id].attributes.title,
"description": state.bees.entities.journals[ownProps.journal.id].attributes.description,
}
};
}, undefined)(EditJournalForm));
and here is my custom input:
InputField.jsx
import {ControlLabel, FormControl, FormGroup} from "react-bootstrap";
import PropTypes from "prop-types";
import React from "react";
const InputField = ({input, label, content, updateFn, type, ...props}) => (
<FormGroup >
<ControlLabel>
{label}
</ControlLabel>
<FormControl
{...props}
{...input}
value={content}
onChange={updateFn}
type={type}
/>
</FormGroup>
);
export default InputField;
InputField.propTypes = {
"input": PropTypes.object.isRequired,
"label": PropTypes.string.isRequired,
"type": PropTypes.string.isRequired,
"content": PropTypes.object,
"updateFn": PropTypes.func
};
Try to call onChange function of input field:
const InputField = ({input, label, content, updateFn, type, ...props}) => (
<FormGroup>
<ControlLabel>
{label}
</ControlLabel>
<FormControl
{...props}
{...input}
value={content}
onChange={(e) => {
input.onChange(e);
updateFn(e);
}}
type={type}
/>
</FormGroup>
);
I see at least one problem - you are assigning the content prop as an object with a val property, but in your custom InputField, you are setting value={content}, so that is actually the object with { val: 'the value' } as opposed to the actual value ('the value' in this example).
With redux-form, it isn't necessary to manually assign from initialValues. By having a name property on the Field, it will be correctly assigned for you.