not getting value in inputbar in react [closed] - javascript

Closed. This question is not reproducible or was caused by typos. It is not currently accepting answers.
This question was caused by a typo or a problem that can no longer be reproduced. While similar questions may be on-topic here, this one was resolved in a way less likely to help future readers.
Closed 5 months ago.
Improve this question
I want to get value filled inside input bar to show inside input bar, I know its sounds illogical but I am new to react and I am following a course
code is below
import React from 'react';
class Searchbar extends React.Component{
state={term :'a'}
// e means event
onChangeHandler=(e)=>{
console.log(e.target.value);
this.setState=({term:e.target.value});
}
render(){
return(
<div className="ui segment">
<form className="ui form">
<div className="field">
<label>Image Search</label>
{/* <input type="text" value={this.state.term} onChange={this.onChangeHandler}/> */}
<input type="text" value={this.state.term} onChange={ e=>(this.setState=({term:e.target.value}),console.log(e.target.value))}/>{/* alternate syntax for event handler */}
</div>
</form>
</div>
)
}
}
export default Searchbar;

You're almost there actually!
A small tweak to your code does the job:
import React from "react";
class Searchbar extends React.Component {
state = { term: "a" };
onChangeHandler = (e) => {
this.setState((state) => {
return { term: e.target.value };
});
};
render() {
return (
<div className="ui segment">
<form className="ui form">
<div className="field">
<label>Image Search</label>
<input
type="text"
value={this.state.term}
onChange={(e) => this.onChangeHandler(e)}
/>
</div>
</form>
</div>
);
}
}
export default Searchbar;
As outlined here, you shouldn't set the state directly.
My recommendation
Personally, I would make a few changes and I'll explain why.
Class vs Functional
My preference goes out to functional components nowadays. With hooks you'll have all the functionality that classes provide, but with less verbose code. (in my experience).
Also, if you're using a very small and limited component like this, setting an object as your state isn't always needed. A simple string would suffice in this use case.
My change
This is what I would personally write if I had to make a simple input component with state.
import { useState } from "react";
const Searchbar = () => {
const [input, setInput] = useState("");
return (
<div className="ui segment">
<form className="ui form">
<div className="field">
<label>Image Search</label>
<input
type="text"
value={input}
onChange={(e) => setInput(e.target.value)}
/>
</div>
</form>
</div>
);
};
export default Searchbar;
I highly recommend you start looking into functional components, if my experience in the field has taught me anything

<input
type="text"
value={this.state.term}
onChange={(e) => (
(this.setState({ term: e.target.value })),
console.log(e.target.value)
)}
/>

Related

I'm getting an error using React: "Invalid DOM property `for`. Did you mean `htmlFor`"

I'm creating a simple CRUD app using React for my front-end, and I'm having trouble with this error:
app.js:21988 Warning: Invalid DOM property `for`. Did you mean `htmlFor`?
Here's my code:
import React, { Component } from 'react';
import axios from 'axios';
export default class Add extends Component {
constructor()
{
super();
this.state={
blogs_name:''
}
}
render() {
return (
<div>
<form>
<div className="form-group">
<label for="blogs_name">Title</label>
<input
type="text"
className="form-control"
id="blogs_name"
value={this.state.blogs_name}
/>
</div>
<button type="submit">Submit</button>
</form>
</div>
);
}
}
I assume that it has to do something with the for property in my label.
Any help is appreciated.
When using React, you can't use the for keyword in JSX, since that's a javascript keyword (remember, JSX is javascript so words like for and class can't be used because they have some other special meaning!)
To circumvent this, React elements use htmlFor instead (see React docs for more information).
So, your render function should be (I only replaced for with htmlFor):
render() {
return (
<div>
<form onSubmit={this.onSubmit} >
<div className="form-group">
<label htmlFor="blogs_name">Title</label>
<input type="text" className="form-control" id="blogs_name"
value={this.state.blogs_name}
onChange={this.onChangeBlogsName} />
</div>
<button type="submit" className="btn btn-primary">Submit</button>
</form>
</div>
);
}
Replace for="" with htmlFor=""
In your case change this
<label for="blogs_name">Title</label>
To this
<label htmlFor="blogs_name">Title</label>
for is a reserved word in JavaScript this is why when it comes to HTML attributes in JSX you need to use something else, React team decided to use htmlFor respectively. You can check the list of attributes from here
Short answer, Remove
for="blogs_name"
In your case.

Whats the proper way to have a form submit data in a stateless react component?

I have a stateless react component that is a little pop up. It takes some data from the user, and passes that back to its parent, where it executes the work.
What is the best way for this component to have a handleSubmit() function, that takes the user input, and sends it back to the parent?
import React, { Component } from "react";
import "../../../node_modules/bulma/css/bulma.css";
const Transfer = (props, token, web3) => {
return (
<div className="modal is-active">
<div className="modal-background" onClick={props.onClick} />
<div className="modal-card">
<section className="modal-card-body">
<div className="content">
<h1 className="title"> Transfer Tokens </h1>
<p className="has-text-danger">
Requires that you are the owner of the token you are transferring
</p>
<p className="subtitle">How it works</p>
<p className="">
Enter the ID of the token you want to transfer, the address to
whom its going to, and thats it!
</p>
//problem area
<form onSubmit={props.onClickSubmit}>
<label htmlFor="text">Address to recieve token</label>
<input
name="Address"
className="input is-info "
required="true"
/>
<label htmlFor="number">Token ID</label>
<input
className="input is-info"
name="Token ID"
type="number"
required="true"
/>
<a className="button is-pulled-right">Submit</a>
</form>
</div>
</section>
<footer className="modal-card-foot is-clearfix">
<a className="button" onClick={props.onClick}>
Cancel
</a>
</footer>
</div>
</div>
);
};
export default Transfer;
I pass in as a prop, onClickSubmit, in my parent component, and that contains the logic for what I'm trying to do.
Very new to stateless react components
It will be difficult to accomplish what you want with a stateless component since you cannot use either refs or state in a stateless component. You can think of a stateless component as a pure function that returns a piece of UI depending on the props you give it.
You could instead use a stateful component and e.g. store the input values in state and call the onClickSubmit prop function with this state when the user submits the form.
If you want to build stateless forms component, I send you a lib that I'm working on:
react-distributed-forms
This allow you to build your Transfer Component this way, (pay attention to use Input instead of input and Button instead of button):
import React, { Component } from "react";
import "../../../node_modules/bulma/css/bulma.css";
import { Input, Button } from "react-distributed-forms";
const Transfer = (props, token, web3) => {
return (
<div className="modal is-active">
<div className="myForm">
<label htmlFor="text">Address to receive token</label>
<Input name="Address" className="input is-info " required="true" />
<label htmlFor="number">Token ID</label>
<Input
className="input is-info"
name="Token ID"
type="number"
required="true"
/>
<Button name="submit" className="button is-pulled-right">
Cancel
</Button>
</div>
</div>
);
};
export default Transfer;
And then in your parent Component, wherever it is in the hierarchy, you simply do:
<Form onSubmit={({ name }) => { console.log(name); }} onFieldChange={({ name, value} ) => { console.log(name, value); }}>
...whatever
<Transfer />
...whatever
</Form>
onFieldChange will receive every input change.
onSubmit will receive the attribute "name" on the Button when you click it.
react-distributed-forms use React context API, so you don't have to pass directly props, it just works. Is built for really dynamic forms...

ReactJS passing state to another class

i have problem in accesing the state on the other component. I am beginner in using the reactjs. I am still confuse on how to use the state and props. I am getting the input which will be set to the state as username then I will pass it to the formDetails component and use it when the handleSubmit triggers. can someone help me I would appreciate any comments, answers, suggestions.
//Components
class DaysForm extends React.Component {
constructor() {
super();
this.state = {
username: ""
};
this.updateInput = this.updateInput.bind(this);
}
onCalculate(e) {
$("#myModal").modal();
}
updateInput(event) {
this.setState({ username: event.target.value });
}
render() {
return (
<div>
<p>How many days are in a full time working week?</p>
<input
type="text"
className="form-control"
onChange={this.updateInput}
/>
<p>How many days a week will this employee work?</p>
<input type="text" className="form-control" />
<br />
<center>
<button
className="btn btn-default"
onClick={this.onCalculate.bind(this)}
>
Calculate
</button>
</center>
</div>
);
}
}
class FormDetails extends React.Component {
constructor(props) {
super(props);
this.handleSubmit = this.handleSubmit.bind(this);
}
handleSubmit(event) {
//console.log here the state that is comming from the component
}
render() {
return (
<div>
<p>Email Address:</p>
<input type="text" className="form-control" />
<p>Business Name:</p>
<input type="text" className="form-control" />
<p>Phone Number:</p>
<input type="text" className="form-control" />
<br />
<center>
<button
className="btn btn-default"
onClick={this.handleSubmit}
>
Submit
</button>
</center>
</div>
);
}
}
From my understanding, you want to set the username in the DaysForm component, and then upon handleSubmit being clicked, it will show up in the FormDetails component. Is that correct?
Assuming so, there are a couple things missing.
First of all, you are not currently rendering FormDetails in the DaysForm. So right now, they have no relation to each other. Or at least not in the code you displayed. Are you using the username as a redux state perhaps which is share in the two components? Because this changes everything if that's the case.
The easier way to do this would be to have FormDetails be a child of DaysForm and then pass the username state as a prop in the FormDetails component. This will make it look something like this:
class DaysForm extends React.Component {
// your code
render(){
return(
<div>
<p>
How many days are in a full time working week?
</p>
<input type="text" className="form-control" onChange={this.updateInput}/>
<p>
How many days a week will this employee work?
</p>
<input type="text" className="form-control"/>
<br></br>
<center>
<button className="btn btn-default" onClick={this.onCalculate.bind(this)}>Calculate</button>
</center>
<FormDetails username={this.state.username}/>
</div>
)
}
}
However, you mentioned that the components have no relation to each other, I am assuming that there are no other components that can connect the two, so this complicates a bit when you want to pass in a state from one component to another. Based on the post's tags, I am assuming you are using Redux. If not, for this case I would encourage you to do so, since it will handle your state in between components. Of course if you haven't touched any of that yet, I will admit it is a whole new can of worms to open.
As for the difference between state and props. State usually belong to a component, you change them causing the component to rerender and they may be later passed in as a props for a child component (as shown in the example code). Props on the other hand come from other components and are immutable. See more here. The way you are using the state in DaysForm seems to be just fine and is as expected, the main challenge here is figuring out how to pass that state to FormDetails when there are no obvious other components in between them.

ReactJS props are updated, but field is not re-rendered

I have been playing around with fields in React, but am running into the issue where a text input is not updating (whilst the properties are). I have tried to do it through a class/state component, but to no avail. I was kind-of hoping to be able to make specific form-only components that are completely cut-off from stores. Can anyone point me in the right direction?
import React from 'react';
export default (props) => {
function editProjectNameChanged(event, syntheticEvent) {
debugger;
props.editProject.name = syntheticEvent.target.value;
}
return (
<div className="col-xs-5 col-md-5">
<form>
<div className="form-group">
<label htmlFor="management-projects-name">Project name</label>
<input type="text" className="form-control" id="management-projects-name"
value={props.editProject.name}
onUserInput={editProjectNameChanged.bind(null, event)}
placeholder="Project name" />
</div>
</form>
</div>
);
}
Thanks in advance.. This whole form thing is more difficult than I thought it would!
You shouldn't change the props in the child. That is a good job for the state. It's not a good idea to update props because parent component is not notified of the change and the state is more useful because when you call setState() the component is redraw. Something like that (I haven't tested it)
import React from 'react';
export class YourComponent extends React.Component{
constructor(){
this.state = {
name: this.props.editProject.name
};
}
editProjectNameChanged(event, syntheticEvent) {
this.setState({
name: syntheticEvent.target.value
});
}
render(){
return <div className="col-xs-5 col-md-5">
<form>
<div className="form-group">
<label htmlFor="management-projects-name">Project name</label>
<input type="text" className="form-control" id="management-projects-name"
value={props.editProject.name}
onUserInput={editProjectNameChanged.bind(this, event)}
placeholder="Project name" />
</div>
</form>
</div>;
}
}
You shouldn't mutate props the way you do it from within a component. If you do not want your component do manage the state, it should instead accept a callback as a prop, that it would call on user input.
The parent component would then decide whether or not, and how, to update the value, and pass it back to your component as a prop.
<input value={ props.value } onChange={ e => props.onChange(e.target.value) } />
Mutating directly the props object has no effect since version 0.13. You can find here the blog post explaining why this behaviour was introduced

Multiple Registration Form with redux and react

I have been trying to develop a dashboard form similiar to airbnb listing form for understanding more deeply about react redux but i am stuck in the middle of my project. I have a multiple form where when user clicks on continue button the user will get another form to fill and so on and if user clicks on back button the user will get form of one step back with previously filled values. I could not decide what should i do for this. Do i have to create a object in action as listingName . summary, name, email etc as empty value and update it with reducer using Object.assign() or what. Till now i could only develop like when user clicks on personal tab a form related to personal information is shown and when user clicks on basic tab, a form related to basic information is shown. I want all form data to be send to server at last submit. What should i do now ? Do i use increment and decrement action for the continue and back button and use submit action on the last form button ? Could you please provide me an idea ?
Here's my code
actions/index.js
export function selectForm(form){
return{
type: 'FORM_SELECTED',
payload: form
};
}
reducers/reducer_active_form.js
export default function(state=null, action){
let newState = Object.assign({},state);
switch(action.type){
case 'FORM_SELECTED':
return action.payload;
}
return state;
}
reducers/reducer_form_option.js
export default function(){
return[
{ option: 'Personal Information', id:1},
{ option: 'Basic Information', id:2 },
{ option: 'Description', id:3},
{ option: 'Location', id:4},
{ option: 'Amenities', id:5},
{ option: 'Gallery', id:6}
]
}
containers/form-details
class FormDetail extends Component{
renderPersonalInfo(){
return(
<div className="personalInfo">
<div className="col-md-4">
<label htmlFor='name'>Owner Name</label>
<input ref="name" type="textbox" className="form-control" id="name" placeholder="Owner name" />
</div>
<div className="col-md-4">
<label htmlFor="email">Email</label>
<input ref="email" type="email" className="form-control" id="email" placeholder="email" />
</div>
<div className="col-md-4">
<label htmlFor="phoneNumber">Phone Number</label>
<input ref="phone" type="textbox" className="form-control" id="phoneNumber" placeholder="phone number" />
</div>
<div className="buttons">
<button className="btn btn-primary">Continue</button>
</div>
</div>
);
}
renderBasicInfo(){
return(
<div>
<h3>Help Rent seekers find the right fit</h3>
<p className="subtitle">People searching on Rental Space can filter by listing basics to find a space that matches their needs.</p>
<hr/>
<div className="col-md-4 basicForm">
<label htmlFor="price">Property Type</label>
<select className="form-control" name="Property Type" ref="property">
<option value="appartment">Appartment</option>
<option value="house">House</option>
</select>
</div>
<div className="col-md-4 basicForm">
<label htmlFor="price">Price</label>
<input type="textbox" ref="price" className="form-control" id="price" placeholder="Enter Price" required />
</div>
<div className="buttons">
<button className="btn btn-primary">Back</button>
<button className="btn btn-primary">Continue</button>
</div>
</div>
);
}
renderDescription(){
return(
<div>
<h3>Tell Rent Seekers about your space</h3>
<hr/>
<div className="col-md-6">
<label htmlFor="listingName">Listing Name</label>
<input ref="name" type="textbox" className="form-control" id="listingName" placeholder="Be clear" />
</div>
<div className="col-sm-6">
<label htmlFor="summary">Summary</label>
<textarea ref="summary" className="form-control" id="summary" rows="3"></textarea>
</div>
<div className="buttons">
<button className="btn btn-primary">Back</button>
<button className="btn btn-primary">Continue</button>
</div>
</div>
);
}
renderLocation(){
return(
<div>
<h3>Help guests find your place</h3>
<p className="subtitle">will use this information to find a place that’s in the right spot.</p>
<hr/>
<div className="col-md-6">
<label htmlFor="city">City</label>
<input ref="city" type="textbox" className="form-control" id="city" placeholder="Biratnagar" />
</div>
<div className="col-md-6">
<label htmlFor="placeName">Name of Place</label>
<input ref="place" type="textbox" className="form-control" id="placeName" placeholder="Ganesh Chowk" />
</div>
<div className="buttons">
<button className="btn btn-primary">Back</button>
<button className="btn btn-primary">Continue</button>
</div>
</div>
);
}
render(){
if ( !this.props.form){
return this.renderPersonalInfo();
}
const type = this.props.form.option;
console.log('type is', type);
if ( type === 'Personal Information'){
return this.renderPersonalInfo();
}
if ( type === 'Basic Information'){
return this.renderBasicInfo();
}
if ( type === 'Description'){
return this.renderDescription();
}
if ( type === 'Location'){
return this.renderLocation();
}
}
}
function mapStateToProps(state){
return{
form: state.activeForm
};
}
export default connect(mapStateToProps)(FormDetail);
The first thing you're missing is controlled components. By giving the inputs a value property, and an onChange function, you will link the input with an external state.
Your components should have access, via react-redux, to the state and actions needed. The value of the form should be your state for that object. So you might have a state like:
location: {
listingName: '123 Main St',
summary: 'The most beautiful place!'
}
Then, you'd just pass each property to inputs. I'm assuming, in this example, that you've passed the location prop in mapStateToProps, and an actions object with all the related actions in mapDispatchToProps:
changeHandler(ev, fieldName) {
const val = ev.target.value;
this.props.actions.updateField(fieldName, val);
},
render() {
return (
<input
value={this.props.location.listingName}
onChange={(ev) => { this.changeHandler(ev, 'listingName'}}
/>
);
}
You provide it an action that can be used to update the state:
function updatefield(field, val) {
return {
type: UPDATE_FIELD,
field,
val
};
}
Then, you just merge it in, in your reducer
switch (action.type) {
case UPDATE_FIELD:
state = { ...state, [action.field]: val };
(using dynamic keys and spread operator for neatness, but it's similar to Object.assign)
All of your form state lives in the Redux store this way. When you are ready to submit that data to the server, you can either use async actions with redux-thunk, or set up some middleware to run the calls. Either way, the strategy is the same; your state lasts locally and populates all your forms, and then is sent to the server when the user submits.
I went through this pretty quick, let me know if you need me to elaborate on anything :)
As you are using react-redux you can use the redux-form. It will greatly help you with the coding as it will simplify your work load and it is also bug-free (as far as I know). In my opinion you would want to use all the libraries/frameworks provided to you as you want to be as agile as possible.
Also the redux-form has a wizard form implementation. I think that is exactly what you are looking for.
http://erikras.github.io/redux-form/#/examples/wizard?_k=yspolv
Just follow the link and you will see a very good tutorial on how to implement it. Should be a piece of cake.

Categories