'How to make redux-form work with Next.js?
I found some answers here at stackoverflow but seems like these procedure not solving the problem. My form is not editable even though I added the form to combineReducers. Any kind of help will be appreciated.
As versions are really important:
"next": "12.0.10",
"next-redux-wrapper": "^6.0.2",
"react": "17.0.2",
"react-dom": "17.0.2",
"react-redux": "^7.2.0",
"redux": "^4.0.5",
"redux-form": "^8.3.8",
"redux-thunk": "^2.2.0"
Node version 16.13.1
store.js
import { createStore, applyMiddleware, compose } from "redux";
import thunk from "redux-thunk";
import { createWrapper } from "next-redux-wrapper";
import rootReducer from "./reducers/rootReducer";
const middleware = [thunk];
const composeEnhancers = (process.env.NODE_ENV === 'development' && typeof window !== 'undefined' )?window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__ || compose: compose;
const makeStore = () => createStore(rootReducer,
composeEnhancers(applyMiddleware(...middleware)));
export const wrapper = createWrapper(makeStore);
rootReducer.js
import { combineReducers } from "redux";
import serviceReducer from "./service-reducer";
import serviceItemsByCategoryReducer from "./serviceItems-reducer";
import { reducer as formReducer} from 'redux-form';
const rootReducer = combineReducers({
serviceReducer: serviceReducer,
serviceItemsByCategoryReducer: serviceItemsByCategoryReducer,
form: formReducer,
})
export default rootReducer;
_app.js
import Layout from '../components/Layout/Layout';
import 'bootstrap/dist/css/bootstrap.css';
import App from "next/app"
import React from "react"
import {wrapper} from "../redux/store"
class MyApp extends App {
static async getInitialProps({Component, ctx}) {
const appProps = Component.getInitialProps ? await Component.getInitialProps(ctx) : {};
return { appProps: appProps };
}
render(){
const { Component, appProps } = this.props;
return(
<>
<Layout>
<Component {...appProps} />
</Layout>
</>
);
}
}
export default wrapper.withRedux(MyApp);
contact.js
import React,{Component} from 'react';
import ContactUsForm from '../components/contact/ContactUsForm';
import { toast } from 'react-toastify';
import * as actions from '../redux/actions/formActions';
export default class ContactUs extends Component {
constructor(){
super();
this.state ={
submitted:false,
errors : []
}
this.contactUs = this.contactUs.bind(this);
}
contactUs(emailData){
actions.contactus(emailData)
.then(
sent =>this.setState({errors:[], submitted: true}),
toast.success("Success"),
errors =>this.setState({errors})
);
}
render() {
const {errors, submitted} = this.state;
return (
<>
<h1 className="contact-shadow-title">Contact us</h1>
{!submitted && <ContactUsForm submitCb={this.contactUs} errors={errors}/>}
{ submitted &&
<div className="contact-title">
<h1>Email Sent Successfully</h1>
</div>
}
</>
)}
}
ContactUsForm.js
import React from 'react';
import { Field, reduxForm } from 'redux-form';
import {BwmInput} from '../shared/form/BwmInput';
import {BwmResError} from '..shared/form/BwmResError';
import {required} from '../shared/form/validators';
let init = {}
let ContactUsForm = props => {
const { handleSubmit, pristine,reset, submitting, submitCb, valid ,errors,initialValues } = props;
init = initialValues
return (
<form onSubmit={handleSubmit(submitCb)} >
<div className="row">
<div className="col-md-4">
<Field
name="first_name"
type="text"
label='First Name'
className='form-control'
component={BwmInput}
validate={[required]}
/>
</div>
</div>
<div className="row">
<div className="col-md-12">
<Field
name="message"
type="text"
label='Message'
rows='6'
className='form-control'
component={BwmTextArea}
validate={[required]}
/>
</div>
</div>
<button className='btn btn-primary btn-bwm btn-form' type="submit" disabled={!valid || pristine || submitting}>
Send
</button>
<button className='btn btn-warning btn-bwm btn-form' type="button" disabled={pristine || submitting} onClick={reset}>
Reset
</button>
<BwmResError errors={errors} />
</form>
)
}
ContactUsForm= reduxForm({
form: 'contactUsForm'
})(ContactUsForm)
export default ContactUsForm;
BwmInput.js
import React from 'react';
export const BwmInput = ({
input,
label,
type,
symbol,
className,
meta: { touched, error, warning }
}) => (
<div className='form-group'>
<label>{label}</label>
<div className='input-group'>
{ symbol &&
<div className='input-group-prepend'>
<div className='input-group-text'>{symbol}</div>
</div>
}
<input {...input} type={type} className={className}/>
</div>
{touched &&
((error && <div className='alert alert-danger'>{error}</div>))}
</div>
)
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|
