React Js input is losing focus when I try typing in it but only when onChange is added
Move useState
to TableRowWithSave
and use value
instead of defaultValue
function ConditionalTableRow(props) {
let { item, index } = props;
if ( index === editModeIndex)
return (<TableRowWithSave item={item} index={index} />)
else
return (<TableRowWithEdit item={item} index={index} />)
}
function TableRowWithSave(props) {
let { item } = props;
const [make, setMake] = useState(item.make);
return (
<TableRow>
<TableCell>
<input type="text" value={make} onChange={e => setMake(e.target.value)} />
</TableCell>
<TableCell>
<button className="palletSaveButton" onClick={handleSaveClick}> Save </button>
</TableCell>
</TableRow>
)
}
const AddMaker = () => {
return (
<TableBody>
{
records.map((item, index) => (
<ConditionalTableRow key={index} item={item} index={index} />
))
}
</TableBody>
);
}
EDIT: Also it's better to move ConditionalTableRow
and TableRowWithSave
outside AddMaker
React input text losing focus on rerender
I found it. Everytime I called ReactDOM.render
I was redeclaring my top-level component function, which seems to cause my input text to lose focus. It must do an identity check on the passed component function/class to see if it's the same as the previous one and completely rerender from scratch if it's not.
So, here's how NOT to do it:
const render = props => {
const App = props => (
<Router history={browserHistory}>
<Switch>
<Route key="/login" path="/login" render={() => View(props)}/>
</Switch>
</Router>
);
ReactDOM.render(
<App {...props}/>,
rootDiv
);
}
render();
render();
Failing jsfiddle here: https://jsfiddle.net/chwsmchd/
Here's the correct way to do it:
const App = props => (
<Router history={browserHistory}>
<Switch>
<Route key="/login" path="/login" render={() => View(props)}/>
</Switch>
</Router>
);
const render = props => {
ReactDOM.render(
<App {...props}/>,
rootDiv
);
}
render();
render();
Correct jsfiddle: https://jsfiddle.net/gzzpmpbz/
Which component needs keys to keep focus after rerender?
onChange = ({ value }) => {
if (this.props.onChange) {
// Check to see if the document value really has changed
if (value.document !== this.state.value.document) {
this.props.onChange(value); // <----- This line is ruining it for you
}
}
this.setState({ value });
};
The indicated line is ruining it for you, I didn't understand what you need it for.
If you want to trigger a callback when the state really changed you should do this via componentWillUpdate(object nextProps, object nextState)
and there compare nextState.value.document
with this.state.value.document
like this:
componentWillUpdate = (object nextProps, object nextState) => {
if (nextState.value.document !== this.state.value.document)
this.props.onChange(nextState.value);
}
...or you could use the setState
callback to trigger code after the state has updated:
onChange = ({ value }) => {
var newDocValue = value.document;
var oldDocValue = this.state.value.document;
this.setState({ value }, () => {
if (oldDocValue !== newDocValue)
this.props.onChange(newDocValue);
});
}
I personally would rewrite the whole component as a function component, as I consider the lifecycle- and change-reaction handling much easier with useEffect
hooks.
Input loses focus after typing character React
You need to move the TestExperience
out of FormTest
.
import React from "react";
import { useState } from "react";
const TestExperience = (props) => {
const [name, setName] = useState("");
return (
<div>
<h1>Test Experience {props.num}</h1>
<input
type="text"
name="name"
placeholder="Name"
onChange={(event) => {
event.preventDefault();
setName(event.target.value);
}}
value={name}
/>
</div>
);
};
const FormTest = () => {
const processFormData = (event) => {
event.preventDefault();
console.log(event.target);
};
const [nums, setNums] = useState([1, 2, 3]);
const arr = nums.map((num, index) => (
<TestExperience num={num} key={index} />
));
return (
<div>
<form
onSubmit={(event) => {
processFormData(event);
}}
>
{arr}
//another way I tried to do it below //
{nums.map((num, index) => (
<TestExperience num={num} key={index} />
))}
<button
onClick={() => {
setNums([...nums, nums.length + 1]);
}}
>
Add one!
</button>
</form>
</div>
);
};
export default FormTest;
Code sandbox => https://codesandbox.io/s/trusting-elbakyan-mxrez?file=/src/App.js
Related Topics
React Open Modal Window on Click in Another Component
Html - Clicking a Button to Obtain Table Cell Value
How to Display JavaScript Datetime in 12 Hour Am/Pm Format
Calculating Sum of Checked Checkboxes
Laravel Reactjs:Changes Are Not Reflecting After Change in My Js(Reactjs) File
Can We Insert JavaScript into Any Webpage Loaded in the Browser
Filereader Onload With Result and Parameter
Get Index on Click of a Mapped Array in React Js
Getting Typeerror: This.Props Is Undefined on Reactjs
Converting Json Object to CSV Format in JavaScript
What Does Webkitformboundary Mean
Get Count of True Values in Json With JavaScript
Angular:How to Add/Remove Files in the Angular
How to Update Component State on Redux State Change
Using Setstate to Change Multiple Values Within an Array of Objects - Reactjs
Image Upload With Preview and Delete Option - Javascript/Jquery