I have a simple Redux Form and tried to follow the example given here https://redux-form.com/6.2.0/docs/GettingStarted.md/ here is my code
user-form.js
import React from 'react';
import {Field, reduxForm} from 'redux-form';
class UserForm extends React.Component {
/**
* User Form goes here...
*/
render() {
const { handleSubmit } = this.props;
return (
<form role="form" onSubmit={handleSubmit}>
<div className="box-body">
<div className="form-group">
<label htmlFor="name">Full Name</label>
<Field
name="name"
component="input"
type="text"
className="form-control"
placeholder="Enter full name..."/>
</div>
<div className="form-group">
<label htmlFor="email">Email address</label>
<Field
name="email"
type="email"
component="input"
className="form-control"
placeholder="Enter email"/>
</div>
<div className="form-group">
<label htmlFor="password">Password</label>
<Field
name="password"
type="password"
component="input"
className="form-control"
placeholder="Password"/>
</div>
</div>
<div className="box-footer">
{/* <button type="submit" className="btn btn-primary">Save</button> */}
<button type="submit" className="btn btn-primary" value="Save">Save</button>
</div>
</form>
);
}
}
UserForm = reduxForm({
form: 'user'
})(UserForm);
export default UserForm;
Above Form is rendered by a UserPage Container
user-page.js
import React from 'react';
import Page from '../../page';
import UserForm from '../components/user-form';
import UserList from '../components/user-list';
import {bindActionCreators} from 'redux';
import {connect} from 'react-redux';
import UserAction from '../actions';
import {showLoading, hideLoading} from 'react-redux-loading-bar';
/**
* We might want to create an Abstract Form component to
* include all common form features.
*/
class UserPage extends Page {
handleUserSubmit(values) {
console.log(values);
}
/**
* Content is loaded into page
*/
content() {
return (
<div className="row">
{/* left column */}
<div className="col-md-6">
{/* general form elements */}
<div className="box box-primary">
<div className="box-header with-border">
<h3 className="box-title">New User</h3>
</div>
{/* /.box-header */}
<UserForm onSubmit={this.handleUserSubmit}/>
</div>
{/* /.box */}
</div>
{/*/.col (left) */}
{/* right column */}
<div className="col-md-6">
{/* UserList made of <User /> */}
{this.userList()}
{/* /.box */}
</div>
{/*/.col (right) */}
</div>
);
}
}
const mapStateToProps = (state) => ({ //this gets state from reducer and maps to props
users: state.userList.users,
fetched: state.userList.fetched,
error: state.userList.error
});
const mapDispatchToProps = (dispatch) => ({
actions: bindActionCreators({
dispatchShowLoading: showLoading,
dispatchHideLoading: hideLoading,
dispatchUserList: UserAction.userList
}, dispatch)
});
export default connect(mapStateToProps, mapDispatchToProps)(UserPage);
My Form successfully renders and I can see all the actions being dispatched inside the Redux Dev tools window, but when I try to enter text into the fields it won't do any thing, however the actions are dispatched like I said.
Sorry if this sounds a very basic question. I am relatively new to React and Redux and for that matter to Javascript.
In order to make redux form work, its reducer needs to be included and I forgot to include one, this fixed my issue.
import { reducer as formReducer } from 'redux-form';
const allReducers = combineReducers({
form: formReducer,
});
export default allReducers;
Related
EDIT: Events are not working at all, the onSubmit and onChange functions are not being called. I have another reactapp with similar form and onChange and onSubmit works OK there.
I have a form I dont want the page to refresh when I click on submit. I tried using preventDefault() but I didnt work. Even onChange is printing anything on console. This form is not on page, I am using React Router to point to='/new' and component={NewPost} (NewPost is in ./components/posts/form)
./components/posts/form.js:
import React, { Component } from "react";
import { connect } from "react-redux";
class NewPost extends Component {
state = {
title: "",
body: "",
status: 0,
};
onSubmit = (e) => {
e.preventDefault();
const post = e;
console.log(post);
};
onChange = (e) => {
console.log(e.target.value);
this.setState({
[e.target.name]: e.target.value,
});
};
render() {
const { title, body, status } = this.state;
return (
<div className="card card-body mt-4 mb-4">
<h2>New Post</h2>
<form onSubmit={this.onSubmit}>
<div className="form-group">
<label>Title</label>
<input
type="text"
name="title"
value={title}
onChange={this.onChange}
className="form-control"
/>
</div>
<div className="form-group">
<label>Content</label>
<textarea
type="text"
name="body"
rows="15"
value={body}
onChange={this.onChange}
className="form-control"
/>
</div>
<div className="form-group">
<button className="btn btn-primary" type="submit">
Submit
</button>
</div>
</form>
</div>
);
}
}
export default NewPost;
App.js:
import React from "react";
import NavBar from "./components/layout/navbar";
import store from "./store";
import { Provider } from "react-redux";
import Dashboard from "./components/posts/dashboard";
import NewPost from "./components/posts/form";
import {
HashRouter as Router,
Route,
Switch,
Redirect,
} from "react-router-dom";
class App extends React.Component {
render() {
return (
<Provider store={store}>
<Router>
<React.Fragment>
<div className="container">
<NavBar />
<Switch>
<Route exact path="/" component={Dashboard}></Route>
<Route exact path="/new" component={NewPost}></Route>
</Switch>
</div>
</React.Fragment>
</Router>
</Provider>
);
}
}
export default App;
Issue is not related to code. I created new react application and moved all my code now everything is working fine.
I am making my react application strictly according to the lessons. But there was such an error, I tried to figure it out all day, but I have no idea why this is happening. The main point is that I have the addProduct function located in the ModalAddProduct component, in fact, it just collects data and passes it to the addProduct function, which is located in the redux / state.js folder, this function simply adds the data passed to it via callback to the state object, in which stores all products. But the problem is that no data is being written. Although when dabbing it is clear that the data comes in, but is not pushed into the array. I tried with other data, same error. Moreover, when debugging, if you hover courses over an array, it shows the added products, but they are not in the array itself (there are screenshots). Also, when rendering on changes was added according to the lessons, the application shows the products, but after the reboot they disappear, since they were not registered in the array of products
export let addProduct = (data) => {
debugger;
state.mainPage.products.push(data);
rerenderF(state);
}
export default state;
import React from 'react';
import ReactDOM from 'react-dom';
import './index.css';
import App from './App';
import reportWebVitals from './reportWebVitals';
import state from './redux/state';
import {addProduct} from './redux/state';
ReactDOM.render(
<React.StrictMode>
<App state={state} addProduct={addProduct}/>
</React.StrictMode>,
document.getElementById('root')
);
reportWebVitals();
import logo from './logo.svg';
import React from 'react';
import Nav from './Components/Navbar/Nav';
import Footer from './Components/Footer/Footer';
import AdminProducts from './Pages/AdminProducts';
import './App.css';
import { BrowserRouter, Route, Router } from 'react-router-dom';
const App = (props) => {
return (
<div>
<Nav></Nav>
<Route path="/products"
render={ () => <AdminProducts products={props.state.mainPage.products} addProduct={props.addProduct}/>} />
<Footer></Footer>
</div>
);
}
export default App;
function App(props) {
return (
<div>
<ProductsList products={props.products} addProduct={props.addProduct} />
</div>
);
}
function ProductList(props) {
return (
<div className="container">
<AddProductButton />
<ModalAddProduct addProduct={props.addProduct}/>
<div className="row">
{props.products.map( product => {
return <ProductAdminCard product={product} />
})}
</div>
</div>
);
}
import { checkPropTypes } from 'prop-types';
import React from 'react';
function ModalAddProduct(props) {
const urlPhoto = 'https://sun9-56.userapi.com/impg/46d6OEAguHzOvhD8gFvtuaKJpgbB2HdpCrR2wQ/rXhMbv1AJnE.jpg?size=800x800&quality=96&proxy=1&sign=1c6396244ef85dbe1ab426308018ddca';
let setPrice = React.createRef();
let setProducer = React.createRef();
let setType = React.createRef();
let setSizes = React.createRef();
let setDescription = React.createRef();
let setTags = React.createRef();
let setPhoto = React.createRef();
const addProduct = () => {
const data = {
id: 9,
"urlPhoto": urlPhoto,
"price": `${setPrice.current.value}`,
"producer": `${setProducer.current.value}`,
"type": `${setType.current.value}`,
"sizes": `${setSizes.current.value}`,
"description": `${setDescription.current.value}`,
"tags": `${setTags.current.value}`
}
props.addProduct(data);
setPrice.current.value = '';
setProducer.current.value = '';
setType.current.value = '';
setSizes.current.value = '';
setDescription.current.value = '';
setTags.current.value = '';
}
return (
<div className="modal fade" id="addProduct" tabindex="-1" role="dialog" aria-hidden="true">
<div className="modal-dialog modal-lg">
<div className="modal-content">
<div className="modal-header">
<h5 className="modal-title" id="exampleModalLabel">Modal title</h5>
<button type="button" className="close" data-dismiss="modal" aria-label="Close">
<span aria-hidden="true">×</span>
</button>
</div>
<div className="modal-body">
<div className="container">
<div className="row justify-content-center">
<div className="col-md-6 text-center">
<figure className="figure">
<img src={urlPhoto} className="figure-img img-fluid rounded profile-img" alt="photo" />
</figure>
</div>
</div>
<div className="row justify-content-center">
<div className="col-md-6">
<form>
<div className="form-group">
<label for="photo">Url photo</label>
<input className="form-control" type="text" id="photo" placeholder="URL" ref={setPhoto} />
<label for="price">Price</label>
<input className="form-control" type="text" id="price" placeholder="Enter price" ref={setPrice} />
<label for="producer">Producer</label>
<input type="text" className="form-control" id="producer" placeholder="Enter producer" ref={setProducer} />
<label for="type">Type</label>
<input type="text" className="form-control" id="type" placeholder="Enter type" ref={setType} />
<label for="sizes">Sizes</label>
<input className="form-control" type="text" id="sizes" placeholder="Enter sizes(use ',')" ref={setSizes} />
<label for="description">Description</label>
<textarea className="form-control" id="description" rows="3" ref={setDescription}></textarea>
<label for="tags">Tags</label>
<input type="text" className="form-control" id="tags" placeholder="Enter tags" ref={setTags} />
</div>
</form>
</div>
</div>
<div className="row justify-content-center">
<div className="col-md-6">
<button className="btn general-button add-button-modal btn-block" onClick={addProduct}>Add product</button>
<button className="btn general-button delete-button btn-block" data-dismiss="modal">Canel</button>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
);
}
export default ModalAddProduct;
I'm building an app with React and I'm trying to implement a modal appearing after error occurring.
This is a simply login card with input boxes and I do a post request to login or sign-up new users.
If there's any error in my form or users already exists I want to popup a modal with error messages like the following.
I can't understand why it isn't showing. The error is ok and the backdrop is visible. Any help is appreciated.
There's my code:
This is the JSX code:
import { useHttpClient } from '../hooks/http-hook';
const { isLoading, error, sendRequest, clearError } = useHttpClient();
...
return (
<React.Fragment>
<ErrorModal error={error} onClear={clearError} />
<div className="container">
{isLoading && <LoadingSpinner asOverlay />}
<div className="card card-container">
<img id="profile-img" className="profile-img-card" alt="Login Avatar" src={require("../../assets/images/avatar.png")} />
<p id="profile-name" className="profile-name-card"></p>
<form className="form-signin" onSubmit={loginSubmitHandler}>
<span id="reauth-email" className="reauth-email"></span>
{!isLoginMode && (
<Input
element="input"
id="username"
type="text"
title="Username"
placeholder="USERNAME"
validators={[VALIDATOR_REQUIRE()]}
errorText="Required."
onInput={inputHandler}
/>
)}
<Input
element="input"
id="email"
type="text"
title="EMAIL"
placeholder="EMAIL"
validators={[VALIDATOR_EMAIL()]}
errorText="Invalid email address."
onInput={inputHandler}
/>
<Input
element="input"
id="password"
type="password"
title="PASSWORD"
placeholder="PASSWORD"
validators={[VALIDATOR_MINLENGTH(5)]}
errorText="Your password must have at least 5 characters."
onInput={inputHandler}
/>
<Button type="submit" disabled={!formState.isValid}>
{isLoginMode ? 'LOGIN' : 'SIGNUP'}
</Button>
</form>
<Button inverse onClick={switchModeHandler}>
SWITCH TO {isLoginMode ? 'SIGNUP' : 'LOGIN'}
</Button>
</div>
</div>
</React.Fragment>
)
This is my Modal.js
import React from 'react';
import ReactDOM from 'react-dom';
import { CSSTransition } from 'react-transition-group';
import Backdrop from './Backdrop';
import './Modal.css';
const ModalOverlay = props => {
const content = (
<div className={`modal ${props.className}`} style={props.style}>
<header className={`modal__header ${props.headerClass}`}>
<h2>{props.header}</h2>
</header>
<form
onSubmit={
props.onSubmit ? props.onSubmit : event => event.preventDefault()
}
>
<div className={`modal__content ${props.contentClass}`}>
{props.children}
</div>
<footer className={`modal__footer ${props.footerClass}`}>
{props.footer}
</footer>
</form>
</div>
);
return ReactDOM.createPortal(content, document.getElementById('modal-hook'));
};
const Modal = props => {
return (
<React.Fragment>
{props.show && <Backdrop onClick={props.onCancel} />}
<CSSTransition
in={props.show}
mountOnEnter
unmountOnExit
timeout={200}
classNames="modal"
>
<ModalOverlay {...props} />
</CSSTransition>
</React.Fragment>
);
};
export default Modal;
And this my ErrorModal.js
import React from 'react';
import Modal from './Modal';
import Button from '../formElements/Button';
const ErrorModal = props => {
return (
<Modal
onCancel={props.onClear}
header="An Error Occurred!"
show={!!props.error}
footer={<Button onClick={props.onClear}>Okay</Button>}
>
<p>{props.error}</p>
</Modal>
);
};
export default ErrorModal;
It was simply my bootstrap.css to create a mess.....
<link rel="stylesheet" href="%PUBLIC_URL%/stylesheets/bootstrap/bootstrap.css">
I simply renamed the modal class in custom_modal
Using redux I created a form and I am able to dispatch actions, validations and is working fine without any issues. But load data/initialize on to form field(ReduxForm) not populating data but code executed, can anyone help me in fixing the issues or where I am going wrong, code executed fine but the data not populating on the respective form fields
import "../../views/CSS/Organization.css";
import { Container, Row, Col } from "react-bootstrap";
import {createOrganization} from "../../store/actions/org_actions"
import {connect} from "react-redux"
import moment from 'moment'
import {Field, reduxForm} from 'redux-form'
class Organization extends Component {
componentDidMount(){
}
renderInputField = (field)=>(
<div class='form-group' >
<div class='oddT-icon-input' >
<input {...field.input} placeholder={`${field.placeHolder}`} class='oddT-text' />
<i class={`${field.icon}`}></i>
</div>
<div class="validation-error">{field.meta.touched?field.meta.error:""}</div>
</div>
)
render() {
return (
<div>
<Row>
<div class='col-sm-6' >
<label htmlFor="fePassword">Organization Name</label>
<Field
name="orgName"
component={this.renderInputField}
placeHolder="Organization Name"
icon="fa fa-user"
/>
</div>
</Row>
);
}
}
function mapStateToProps(state,props){
console.log(state)
return {
success: {orgName:"ARSCCOM"},
initialValues :{orgName:"ARSCCOM"}
}
}
export default reduxForm({
validate,
form: 'Organization',
enableReinitialize : true
})(connect(mapStateToProps,{createOrganization})(Organization))
Thank you so much
I´m learning in react and practicing making a simple application to login and view messages sent.
I´ve read a lot about routing, links and redirect, but i couldn´t translate to my app.
I Would like to click in the "Login" button of a component and redirect to another component.
Here i have the principal component : App.js
import React, { Component } from 'react';
import { BrowserRouter as Router, Route, Link, Switch } from 'react-router-dom';
class Login extends Component {
state = {
loggedIn:false
};
loginHandle = () => {
this.setState({loggedIn:true});
}
render(){
return (
<div className="container d-flex h-100">
<div className="row align-self-center w-100">
<div className="col-6 mx-auto">
<div className="jumbotron">
<form name="form1">
<fieldset>
<legend>Chat App</legend>
<label for="UserName" className="col-form-label">Username</label>
<input type="text" className="form-control col-12" id="UserName"></input>
<label for="Password" className="col-form-label">Password</label>
<input type="text" className="form-control col-12" id="Password"></input>
<button type="button" value="log in" className="btn btn-secondary" onClick={this.loginHandle}>Login</button>
</fieldset>
</form>
<div style={{float:"right"}}>
<div className="login-help ">
Register - Forgot Password
</div>
</div>
</div>
</div>
</div>
</div>
);
}
}
export default Login;
I wrapped all the Links in a Navigation component
So, when i route /, it goes to the Login component
class Login extends Component {
state = {
loggedIn:false
};
loginHandle = () => {
this.setState({loggedIn:true});
}
render(){
return (
<div className="container d-flex h-100">
<div className="row align-self-center w-100">
<div className="col-6 mx-auto">
<div className="jumbotron">
<form name="form1">
<fieldset>
<legend>Chat App</legend>
<label for="UserName" className="col-form-label">Username</label>
<input type="text" className="form-control col-12" id="UserName"></input>
<label for="Password" className="col-form-label">Password</label>
<input type="text" className="form-control col-12" id="Password"></input>
<button type="button" value="log in" className="btn btn-secondary" onClick={this.loginHandle}>Login</button>
</fieldset>
</form>
<div style={{float:"right"}}>
<div className="login-help ">
Register - Forgot Password
</div>
</div>
</div>
</div>
</div>
</div>
);
}
}
export default Login;
Do i have to import routes and redirect in the Login component, or i have to mange all from the App component?
Sorry about this mess, but i don´t know how to continue
Thanks a lot. I really apreciatted in advance.
The simplest way for navigating to another route.
For example you can wrap your Forgot password like following:
<Link to="/forgotRoute">Forgot password?</Link>
Don't forget to add /forgotRoute handling into your Navigator config (where you routed / to your Login component).
Hope it helps.
The correct way for what you want i think it is. So follow me..
You need to use router. In my case i'm using react-router-dom.
First router App component, by default page its renders DefaultPage components and in DefaultPage when component mounted you can render client anywhere.
index.js looks like:
import React from 'react';
import ReactDOM from 'react-dom';
import { BrowserRouter } from 'react-router-dom';
import { Route, Switch } from 'react-router-dom';
class DefaultPage extends Component {
state = {
autorized: false,
mounted: false,
}
componentDidMount = () => {
const { autorized } = this.state;
if (!autorized) {
this.props.history.push('/login');
return;
}
this.setState({
mounted: true,
});
}
render = () => {
if (!this.state.mounted) {
return (
<React.Fragment>
<p>Waiting...</p>
</React.Fragment>
)
}
return (
<React.Fragment>
<p>Hello...</p>
</React.Fragment>
)
}
}
class Login extends React.Component {
handleLogin = () => {
if (contidion) {
this.props.history.push('/');
}
}
render = () {
return (
<button onClick={this.handleLogin}>Click to login</button>
)
}
}
class App extends React.Component {
render = () {
return (
<Switch>
<Route exact path="/" component={DefaultPage} />
<Route path="/login" component={Login} />
<Route component={DefaultPage} />
</Switch>
)
}
}
ReactDOM.render(
<BrowserRouter >
<App />
</BrowserRouter>,
document.getElementById("root")
);