this is my first question here,pardon me for any mistake. So ,I have a few inputs and for displaying the values of them I used some elements like h1 and div's which are in a seperate component. I want my elements to have some default value, so for that I kept them in state and then I call an onChange function on inputs which will update my elements state. I tried doing it with event.target like nameElement:event.target.value ,it would have worked if i had one input but because I have multiple inputs ,when I change an input field it gets overwritten by the one I change next. So how can I update only the input field I change. Like if I write something in name input field only the element of CV which is holding the name field should change . Here's my code sandbox link https://codesandbox.io/s/cool-glitter-9w2mh?file=/src/App.js
I am not sure, I got the issue right. But I got into the sandbox and below are my observations.
I would advise using Formik if you are dealing with the user-input form. Link - https://formik.org/docs/tutorial
Since you have created a single state that contains default value as well as user input value, any changes made by the user is not saved after clicking on "viewCV" link that re-renders entire component.
Changes Required
Have two states : initialData and userDetails.
Modify handleChange
handleChange = (input, e) => {
this.setState((prevState) => {
return {
...prevState,
[input]: e.target.value
};
});
};
In components such as workExp, education make sure you link handleChange as an arrow function for the "onChange" event.
<input onChange={(e) => handleChange("job", e)}>Email
Modify submit button to render the Resume template with user inputted values.
Modify viewCV link which is causing entire parent component re-rendering.
Related
Hello:) I am writing simple application(similar to to-do-list). The task is to add such functionality as the ability to change the title of the announcement.
You add the title and description of the announcement and click on "submit" button -> https://prnt.sc/tf8zxl
the annoncement appears below and you need to have the ability to change the title of it(rename it)->https://prnt.sc/tf8xa2
I added the input when click on the title but it does not allow to write inside it and I do not have any ideas on how to save it in this.state.data correctly.
here is the source code -> https://codesandbox.io/s/eager-darkness-uh9xl?file=/src/App.js
Controlled input
If you need controlled input you have to change values somehow. You are not changing anything at this moment and you are calling handleChange which changes state.title, not state.data[someIndex].title - so the value cannot be changed.
I've provided modified solution where is updating finnished.
Uncontrolled input
If you are OK with uncontrolled input you are probably looking for input attribute defaultValue instead of value. It doesn't change because you are not changing value at all so it's being instantly re-rendered with original value from this.props.data.title.
I've set value by attribute defaultValue and changed onChange on onBlur so update will triger only when you lose focus.
Your modified codesandbox.
Use input in this way
const [title,setTitle] = useState('')
<input type="text" value={title} onChange={(e)=>setTitle(e.target.value)} />
I'm trying to integrate react-day-picker's DayPicker with react-final-form.
React Final Form requires the use of a Field for each form field, which means creating an adapter component whenever you want to a third-party form element to be usable within the form. The adapter component has to accept an input object containing value and onChange. The advice is just to provide a new onChange.
This approach, which works for many other components, doesn't work for DayPicker. It seems like the issue is that DayPicker doesn't actually have an onChange method, so it's up to us to manage what happens when the calendar changes and then store the dates in value property that react-final-form expects.
I've created a codepen here: https://codesandbox.io/s/github/pcraig3/date-picker-sandbox
I have a handleDayClick method in Calendar.js which runs when days are clicked, but onChange isn't being triggered for the calendar consistently.
selectedDays is being updated immediately within the Calendar itself, but the Form is not getting the correct dates until the calendar is unfocused
The form's validate method is only being called once (the first time selecting a day), whereas it is called each time the native text input value is updated.
I would like the form values to be synced up with the calendar's external state and for the validate method to be triggered each time a day is clicked/unclicked. Is this possible to achieve or am I doing completely the wrong thing?
It's probably easier to use the <DayPickerInput> component, instead. That component uses a standard HTML input, which supports onChange. I did it like this:
<Field name={id}>
{({ input, meta }) => (
<React.Fragment>
<label htmlFor={id}>Date: </label>
<DayPickerInput
{...input}
onDayChange={day => input.onChange(day)}
inputProps={{ id: id }}
/>
{meta.error && meta.touched && <div className="error">{meta.error}</div>}
</React.Fragment>
)}
</Field>
According to the documentation, you can add the logic to the "inputProps" prop, since this takes in props to the input component, you can also add css to it as well.
inputProps Object
: Additional props to add to the input component.
Your code will look like this:
const dateChanged = day => (console.log(day)); //function to call when date changes
inputProps={{
style: styles.dayPickerInput,
onChange: event => dateChanged(event.target.value),
}}
If you use onDayChange alone, it'll fire after the user "clicks" to select a day, not when the user actually types a date inside the input field, using this extra onchange listener will be a safeguard for you, if the input field is enabled for users to type in the date, which they might.
I have a form, which is populated using various types of question fields (e.g. text input, email, number, radio box, tags, custom inputs ). These field types are fetched dynamically based on prior choices of user on a previous form.
Now, I have to validate the different form fields when user submits the form using React. The issue is that I can't simply check the value attribute of the fields, since some fields are complex and we get the value after applying some calculation, replacing-non-numbers, or some fields may have radio buttons and corresponding text inputs etc. How can I go about this validation in React? My general structure is this:
<form>
{ this.props.questions.map((question, index) => {
return <Question key={index} data={question} validationError={this.state.validationErrors[question.name]} />
})}
</form>
<button onClick={this.validateFields}>Submit</button>
Is it possible to loop through components in validateFields method of this component class? Or I need to loop through the html nodes that are rendered in the final HTML?
Earlier I was doing this using jQuery and was looping through the question div elements and applying custom validation rules depending on the question type (stored in a data attribute).
Now, I am not sure what is the correct way to do this in React.
You're applying jQuery (and vanilla JS) patterns of thinking to React. I suggest to stop considering you have DOM in any form. No DOM, no components list either, do not touch it or React will be a pain instead of help.
All the data you want to have must be in state. That's the purpose of this library.
So, in your case it is better to go this way:
1) Implement onChange event in Question and other field components. Regardless of how complex they are, your could stream their data into a signle argument, aren't you?
2) Add onChange handler in your form with something like
onChange={value =>
this.setState({
fieldValues: {
[index]: value
}
})
}
3) Populate fieldValues like this:
constructor(props) {
super(props);
this.state = {
fieldValues: props.questions,
};
}
And voila - all the form data are already in this.state.fieldValues, ready for any ongoing usage.
Surprised? So I was, when I first been understanding user input in React. Check this section in React docs for the source of the idea: https://reactjs.org/docs/forms.html#controlled-components
I have a simple hidden input field in my React Redux-Form and the value of the field is set by some Google Tag Manager code that basically does document.getElementById('gtm_field').value = 'some value'
The onchange event never gets fired and therefore the value of the form field never gets set in my Redux store. What is the recommended way to approach this problem? Note that I can modify the GTM code that is added to the page do trigger HTML element events, but it has to be added 'outside' the context of my React app.
Is there a simple way to set the value of a redux-form input field from 'external' JS?
You should use the function change() in redux-form props, it could change the value of a field in the Redux store. The usage like this:
handleChange() {
this.props.change(field:String, value:any)
}
I have a form with some input fields (some of them hidden until a checkbox is checked. When I check/uncheck the checkbox a specific state is set (this.state.isChecked = true/false).
On render method, i have a div (containing some input fields) with some classes and this condition for "show" class: <div className={'extra-fields ' + (this.state.isChecked? ' show' : '')}>...</div>
Expected behavior is that on state change, only the "show" class is putted or deleted from div
Current behavior: the entire form is rendered again and all data written in the input fields are lost.
How it should be done this?
If the value of the input fields is important (which they apparently are), and if they can change (which the obviously can), then React should be aware of them, typically in state.
The 'standard' (on only) react way to maintain the contents of the input fields is:
put the content of the input fields in state as well,
include something like value={this.state.foo} and onChange={this._onChange()} to the render of each input field
include the _onChange() function to the form to handle input changes
That way, whenever the form is re-rendered (after each setState()), the input values are also preserved.
PS: The question title "stop reactjs component from rerender on state change" does not really cover the question from text: you are asking for a partial re-render: do re-render the show/hide extra fields based on checkbox, but do not re-render input fields.
The short answer is that you can prevent a component from rendering/updating with the shouldUpdateComponent life-cycle event: https://facebook.github.io/react/docs/react-component.html#shouldcomponentupdate
However, I agree with the previous answer, that for the sake of doing what sounds like a partial re-render, and to follow best practices in general, you should be storing the state of your input fields somewhere in a component so that they persist beyond a render call.