React.js - 재렌더 시 입력이 초점을 잃음
요.onChange
: ★★★★★★★setState
반응하다. UI하다, 반응하다.문제는 텍스트 입력이 항상 초점을 잃기 때문에 각 문자:D에 대해 다시 초점을 맞춰야 한다는 것입니다.
var EditorContainer = React.createClass({
componentDidMount: function () {
$(this.getDOMNode()).slimScroll({height: this.props.height, distance: '4px', size: '8px'});
},
componentDidUpdate: function () {
console.log("zde");
$(this.getDOMNode()).slimScroll({destroy: true}).slimScroll({height: 'auto', distance: '4px', size: '8px'});
},
changeSelectedComponentName: function (e) {
//this.props.editor.selectedComponent.name = $(e.target).val();
this.props.editor.forceUpdate();
},
render: function () {
var style = {
height: this.props.height + 'px'
};
return (
<div className="container" style={style}>
<div className="row">
<div className="col-xs-6">
{this.props.selected ? <h3>{this.props.selected.name}</h3> : ''}
{this.props.selected ? <input type="text" value={this.props.selected.name} onChange={this.changeSelectedComponentName} /> : ''}
</div>
<div className="col-xs-6">
<ComponentTree editor={this.props.editor} components={this.props.components}/>
</div>
</div>
</div>
);
}
});
나머지 코드를 보지 않고 추측할 수 있습니다.Editor Container를 생성할 때 구성 요소에 대한 고유한 키를 지정하십시오.
<EditorContainer key="editor1"/>
재렌더링이 발생했을 때 같은 키가 나타나면 React에 Clobber하지 말고 보기를 재생성하지 말고 재사용하라는 메시지가 다시 표시됩니다.그러면 초점을 맞춘 항목이 계속 초점을 맞춰야 합니다.
나는 계속해서 이곳에 돌아오고 항상 마지막에 다른 곳에 대한 해결책을 찾는다.다시 잊어버릴 것 같아서 여기서 기록하겠습니다!
★★input
제 경우 집중력을 잃었다는 건 제가 재렌더링을 하고 있었기 때문입니다input
★★★★★★★★★★★★★★★★★★
버기 코드:
import React from 'react';
import styled from 'styled-components';
class SuperAwesomeComp extends React.Component {
state = {
email: ''
};
updateEmail = e => {
e.preventDefault();
this.setState({ email: e.target.value });
};
render() {
const Container = styled.div``;
const Input = styled.input``;
return (
<Container>
<Input
type="text"
placeholder="Gimme your email!"
onChange={this.updateEmail}
value={this.state.email}
/>
</Container>
)
}
}
문제는 항상 모든 것을 한 곳에서 코딩하여 빠르게 테스트하고 나중에 다른 모듈로 분할한다는 것입니다.그러나 이 전략은 입력 변경 시 상태를 업데이트하면 렌더링 기능이 트리거되고 포커스가 손실되기 때문에 역효과를 가져옵니다.
, '를 처음부터 모듈화를 수행합니다.즉, 다음과 같습니다.Input
의 render
고정 코드
import React from 'react';
import styled from 'styled-components';
const Container = styled.div``;
const Input = styled.input``;
class SuperAwesomeComp extends React.Component {
state = {
email: ''
};
updateEmail = e => {
e.preventDefault();
this.setState({ email: e.target.value });
};
render() {
return (
<Container>
<Input
type="text"
placeholder="Gimme your email!"
onChange={this.updateEmail}
value={this.state.email}
/>
</Container>
)
}
}
솔루션 참조: https://github.com/styled-components/styled-components/issues/540#issuecomment-283664947
일 <Route/>
render
소품component
.
<Route path="/user" render={() => <UserPage/>} />
은, 「중요」가입니다.component
는 ""를 사용합니다.React.createElement
매번 변경 사항을 다시 적용하는 대신 말이죠.
자세한 내용은 이쪽:https://reacttraining.com/react-router/web/api/Route/component
갈고리와 같은 증상이 있었어요.하지만 문제는 부모 내부의 컴포넌트를 정의하는 것이었습니다.
틀렸다:
const Parent =() => {
const Child = () => <p>Child!</p>
return <Child />
}
오른쪽:
const Child = () => <p>Child!</p>
const Parent = () => <Child />
제 대답은 @z5h가 말한 것과 비슷합니다.
경우에는 ★★★★★★★★★★★★★★★★★★★★★★.Math.random()
한 것을 내다key
컴포넌트용입니다.
는 ★★★★★★★★★★★★★★★★★★★★★★★★★key
는 특정 컴포넌트의 리렌더를 트리거하기 위해서만 사용되며, 어레이 내의 모든 컴포넌트를 리렌더하는 경우는 없습니다(코드로 컴포넌트 배열을 반환합니다).재렌더링 후 상태 회복에 사용되는지 몰랐습니다.
그걸 없앤 게 나한테는 효과가 있었어.
의 적용autoFocus
input
요소는 초점을 맞출 필요가 있는 입력이1개뿐인 상황에서 회피책으로 기능합니다. a는 a, a는 a, a, a는 a, a, a는 a, akey
이기 때문에 만 아니라 input
주요 구성 요소의 재조정에 초점을 잃지 않도록 요소를 자체 구성 요소로 변환합니다.
가 한 '아까'를 이다.value
을 대다defaultValue
두 변경은 두두 and and and and 。onChange
to event event event 。onBlur
.
저도 같은 행동을 했어요.
코드의 문제는 다음과 같은 jsx 요소의 중첩된 배열을 작성한 것입니다.
const example = [
[
<input value={'Test 1'}/>,
<div>Test 2</div>,
<div>Test 3</div>,
]
]
...
render = () => {
return <div>{ example }</div>
}
이 중첩된 배열의 모든 요소는 상위 요소를 업데이트할 때마다 다시 렌더링됩니다.따라서 입력이 매번 "ref" 프로포트를 잃게 됩니다.
내부 어레이를 반응 컴포넌트로 변환하는 문제를 수정했습니다(렌더 기능이 있는 함수).
const example = [
<myComponentArray />
]
...
render = () => {
return <div>{ example }</div>
}
편집:
" " " " " " 을 문제가 합니다.React.Fragment
const SomeComponent = (props) => (
<React.Fragment>
<label ... />
<input ... />
</React.Fragment>
);
const ParentComponent = (props) => (
<React.Fragment>
<SomeComponent ... />
<div />
</React.Fragment>
);
입력의 키 속성 및 부모 요소를 삭제하는 동일한 문제를 해결했습니다.
// Before
<input
className='invoice_table-input invoice_table-input-sm'
type='number'
key={ Math.random }
defaultValue={pageIndex + 1}
onChange={e => {
const page = e.target.value ? Number(e.target.value) - 1 : 0
gotoPage(page)
}}
/>
// After
<input
className='invoice_table-input invoice_table-input-sm'
type='number'
defaultValue={pageIndex + 1}
onChange={e => {
const page = e.target.value ? Number(e.target.value) - 1 : 0
gotoPage(page)
}}
/>
제공된 답변은 도움이 되지 않았습니다. 제가 한 일은 이렇습니다만, 저는 독특한 상황이 있었습니다.
코드를 정리하기 위해 컴포넌트를 다른 파일로 가져올 준비가 될 때까지 이 형식을 사용하는 경향이 있습니다.
render(){
const MyInput = () => {
return <input onChange={(e)=>this.setState({text: e.target.value}) />
}
return(
<div>
<MyInput />
</div>
)
하지만 이 때문에 초점을 잃었어요. 코드를 div에 직접 넣었더니 작동했어요.
return(
<div>
<input onChange={(e)=>this.setState({text: e.target.value}) />
</div>
)
왜 그런지 모르겠어요.이렇게 쓰는 데 문제가 생긴 건 이것뿐이에요.제가 가지고 있는 대부분의 파일에서는 이 작업을 하고 있습니다만, 같은 작업을 하고 있는 사람이 있으면, 그 때문에 포커스가 흐트러집니다.
가 다른 컨테이너 ) (즉, 요소)는 다음과 같습니다.<div key={"bart"}...><input key={"lisa"}...> ... </input></div>
-- 생략된 코드를 나타내는 줄임표는 컨테이너 요소(입력 필드뿐만 아니라)에 고유하고 일정한 키가 있어야 합니다.그렇지 않으면 React는 자녀의 상태가 업데이트될 때 단순히 이전 컨테이너를 다시 렌더링하는 것이 아니라 완전히 새로운 컨테이너 요소를 렌더링합니다.논리적으로는 하위 요소만 업데이트해야 하지만...
많은 주소 정보를 가지고 있는 컴포넌트를 작성하려고 하다가 문제가 발생했습니다.작업 코드는 다음과 같습니다.
// import react, components
import React, { Component } from 'react'
// import various functions
import uuid from "uuid";
// import styles
import "../styles/signUp.css";
export default class Address extends Component {
constructor(props) {
super(props);
this.state = {
address1: "",
address2: "",
address1Key: uuid.v4(),
address2Key: uuid.v4(),
address1HolderKey: uuid.v4(),
address2HolderKey: uuid.v4(),
// omitting state information for additional address fields for brevity
};
this.handleChange = this.handleChange.bind(this);
}
handleChange(event) {
event.preventDefault();
this.setState({ [`${event.target.id}`]: event.target.value })
}
render() {
return (
<fieldset>
<div className="labelAndField" key={this.state.address1HolderKey} >
<label className="labelStyle" for="address1">{"Address"}</label>
<input className="inputStyle"
id="address1"
name="address1"
type="text"
label="address1"
placeholder=""
value={this.state.address1}
onChange={this.handleChange}
key={this.state.address1Key} ></input >
</div>
<div className="labelAndField" key={this.state.address2HolderKey} >
<label className="labelStyle" for="address2">{"Address (Cont.)"}</label>
<input className="inputStyle"
id="address2"
name="address2"
type="text"
label="address2"
placeholder=""
key={this.state.address2Key} ></input >
</div>
{/* omitting rest of address fields for brevity */}
</fieldset>
)
}
}
날카로운 눈을 가진 독자들은 주의할 것이다.<fieldset>
포함 요소이지만 키가 필요하지 않습니다.이 일어나다<>
그리고.<React.Fragment>
또는 심지어<div>
왜요? 아마 바로 옆에 있는 컨테이너만 열쇠가 필요할 거예요.나도 몰라.수학 교과서에서 말하는 것처럼, 설명은 독자들에게 연습으로 남겨진다.
이 문제가 있었습니다만, 기능 컴포넌트를 사용하고 있어 부모 컴포넌트의 상태와 링크하고 있는 것이 문제였습니다.클래스 컴포넌트를 사용하는 것으로 바꾸면 문제가 없어집니다.기능 컴포넌트를 사용할 때 간단한 아이템 렌더러 등에게 훨씬 편리하기 때문에 이 문제를 해결할 방법이 있기를 바랍니다.
저는 이 문제에 부딪혀 도움을 청하러 왔습니다.CSS 체 ! 에는 음음음음음음음음음음음을 사용할 수 .user-select: none;
그렇지 않으면 아이패드에서는 동작하지 않습니다.
그 주된 이유는 다음과 같습니다.리액트 리렌더 시 이전 DOM 참조는 무효가 됩니다.즉, 리액트가 DOM 트리를 변경했고, 사용자는 this.refs.input을 변경했습니다.여기에 입력된 정보가 더 이상 존재하지 않기 때문에 포커스가 작동하지 않습니다.
이것은 검색 입력 상자가 검색 결과 목록과 동일한 컴포넌트(UserList라고 함)에 렌더링되었기 때문에 발생한 것입니다.따라서 검색 결과가 변경될 때마다 입력 상자를 포함한 UserList 구성 요소 전체가 다시 렌더링되었습니다.
저의 솔루션은 UserList와는 다른 UserListSearch라는 완전히 새로운 컴포넌트를 만드는 것이었습니다.User List Search의 입력 필드에 키를 설정할 필요가 없었습니다.Users Container의 렌더링 함수는 다음과 같습니다.
class UserContainer extends React.Component {
render() {
return (
<div>
<Route
exact
path={this.props.match.url}
render={() => (
<div>
<UserListSearch
handleSearchChange={this.handleSearchChange}
searchTerm={this.state.searchTerm}
/>
<UserList
isLoading={this.state.isLoading}
users={this.props.users}
user={this.state.user}
handleNewUserClick={this.handleNewUserClick}
/>
</div>
)}
/>
</div>
)
}
}
이게 누군가에게도 도움이 되길 바라.
★★★★★★★★★★★를 바꿨다.value
을 대다defaultValue
전 좋아요.
...
// before
<input value={myVar} />
// after
<input defaultValue={myVar} />
의 문제는 으로 키의 이 경우,는 key{{키입니다.}키입니다.${item.name}-${index}
}. 으로 하여 요소가 그래서 item.name을 값으로 하여 입력을 변경하려고 하면 키도 변경되어 해당 요소가 인식되지 않습니다.
태그 입력에 다음 코드가 포함되었습니다.
ref={(input) => {
if (input) {
input.focus();
}
}}
이전:
<input
defaultValue={email}
className="form-control"
type="email"
id="email"
name="email"
placeholder={"mail@mail.com"}
maxLength="15"
onChange={(e) => validEmail(e.target.value)}
/>
그 후:
<input
ref={(input) => {
if (input) {
input.focus();
}
}}
defaultValue={email}
className="form-control"
type="email"
id="email"
name="email"
placeholder={"mail@mail.com"}
maxLength="15"
onChange={(e) => validEmail(e.target.value)}
/>
저도 비슷한 문제가 있었는데, 이것으로 해결되었습니다.
const component = () => {
return <input onChange={({target})=>{
setValue(target.vlaue)
}
} />
}
const ThisComponentKeptRefreshingContainer = () => {
return(
<component />
)
}
const ThisContainerDidNot= () => {
return(
<> {component()} </>
)
}
그러나 코드 그림에서는 컴포넌트를 엘리먼트처럼 차일드라고 부르기 때문에 함수처럼 부르면 재렌더링 효과를 얻을 수 없었습니다.도움이 되기를 바라다
html 테이블에서도 같은 문제가 있었습니다.열 안에 텍스트 행을 입력합니다.루프 내에서 나는 json 객체를 읽었고, 특히 입력 텍스트가 있는 열을 만들었다.
http://reactkungfu.com/2015/09/react-js-loses-input-focus-on-typing/
나는 다음과 같은 방법으로 그것을 해결할 수 있었다.
import { InputTextComponent } from './InputTextComponent';
//import my inputTextComponent
...
var trElementList = (function (list, tableComponent) {
var trList = [],
trElement = undefined,
trElementCreator = trElementCreator,
employeeElement = undefined;
// iterating through employee list and
// creating row for each employee
for (var x = 0; x < list.length; x++) {
employeeElement = list[x];
var trNomeImpatto = React.createElement('tr', null, <td rowSpan="4"><strong>{employeeElement['NomeTipologiaImpatto'].toUpperCase()}</strong></td>);
trList.push(trNomeImpatto);
trList.push(trElementCreator(employeeElement, 0, x));
trList.push(trElementCreator(employeeElement, 1, x));
trList.push(trElementCreator(employeeElement, 2, x));
} // end of for
return trList; // returns row list
function trElementCreator(obj, field, index) {
var tdList = [],
tdElement = undefined;
//my input text
var inputTextarea = <InputTextComponent
idImpatto={obj['TipologiaImpattoId']}//index
value={obj[columns[field].nota]}//initial value of the input I read from my json data source
noteType={columns[field].nota}
impattiComposite={tableComponent.state.impattiComposite}
//updateImpactCompositeNote={tableComponent.updateImpactCompositeNote}
/>
tdElement = React.createElement('td', { style: null }, inputTextarea);
tdList.push(tdElement);
var trComponent = createClass({
render: function () {
return React.createElement('tr', null, tdList);
}
});
return React.createElement(trComponent);
} // end of trElementCreator
});
...
//my tableComponent
var tableComponent = createClass({
// initial component states will be here
// initialize values
getInitialState: function () {
return {
impattiComposite: [],
serviceId: window.sessionStorage.getItem('serviceId'),
serviceName: window.sessionStorage.getItem('serviceName'),
form_data: [],
successCreation: null,
};
},
//read a json data soure of the web api url
componentDidMount: function () {
this.serverRequest =
$.ajax({
url: Url,
type: 'GET',
contentType: 'application/json',
data: JSON.stringify({ id: this.state.serviceId }),
cache: false,
success: function (response) {
this.setState({ impattiComposite: response.data });
}.bind(this),
error: function (xhr, resp, text) {
// show error to console
console.error('Error', xhr, resp, text)
alert(xhr, resp, text);
}
});
},
render: function () {
...
React.createElement('table', {style:null}, React.createElement('tbody', null,trElementList(this.state.impattiComposite, this),))
...
}
//my input text
var inputTextarea = <InputTextComponent
idImpatto={obj['TipologiaImpattoId']}//index
value={obj[columns[field].nota]}//initial value of the input I read //from my json data source
noteType={columns[field].nota}
impattiComposite={tableComponent.state.impattiComposite}//impattiComposite = my json data source
/>//end my input text
tdElement = React.createElement('td', { style: null }, inputTextarea);
tdList.push(tdElement);//add a component
//./InputTextComponent.js
import React from 'react';
export class InputTextComponent extends React.Component {
constructor(props) {
super(props);
this.state = {
idImpatto: props.idImpatto,
value: props.value,
noteType: props.noteType,
_impattiComposite: props.impattiComposite,
};
this.updateNote = this.updateNote.bind(this);
}
//Update a inpute text with new value insert of the user
updateNote(event) {
this.setState({ value: event.target.value });//update a state of the local componet inputText
var impattiComposite = this.state._impattiComposite;
var index = this.state.idImpatto - 1;
var impatto = impattiComposite[index];
impatto[this.state.noteType] = event.target.value;
this.setState({ _impattiComposite: impattiComposite });//update of the state of the father component (tableComponet)
}
render() {
return (
<input
className="Form-input"
type='text'
value={this.state.value}
onChange={this.updateNote}>
</input>
);
}
}
심플한 솔루션:
<input ref={ref => ref && ref.focus()}
onFocus={(e)=>e.currentTarget.setSelectionRange(e.currentTarget.value.length, e.currentTarget.value.length)}
/>
ref
이 「」를 트리거 합니다.onFocus
끝 부분을 계산하고 그에 따라 커서를 설정합니다.
이 경우 Input Container 컴포넌트와 입력 필드 자체에 Math.random()을 사용하여 설정했던 주요 소품 값이 생성되었다는 문제가 있었습니다.값의 특성이 일정하지 않아 편집 중인 입력 필드를 추적하기가 어려웠습니다.
저는 포털 안에 텍스트 영역을 가지고 있었습니다.이 텍스트 영역은 초점을 잃었습니다.버그가 많은 포털의 실장은 다음과 같습니다.
export const Modal = ({children, onClose}: modelProps) => {
const modalDOM = document.getElementById("modal");
const divRef = useRef(document.createElement('div'));
useEffect(()=>{
const ref = divRef.current;
modalDOM?.appendChild(ref);
return ()=>{
modalDOM?.removeChild(ref);
}
});
const close = (e: React.MouseEvent) => {
e.stopPropagation();
onClose();
};
const handleClick = (e: React.MouseEvent) => {
e.stopPropagation()
}
return (
createPortal(
<div className="modal" onClick={close}>
<div className="modal__close-modal" onClick={close}>x</div>
{children}
</div>,
divRef.current)
)
}
const Parent = ({content: string}: ParentProps) => {
const [content, setContent] = useState<string>(content);
const onChangeFile = (e: React.MouseEvent) => {
setContent(e.currentTarget.value);
}
return (
<Modal>
<textarea
value={content}
onChange={onChangeFile}>
</textarea>
</Modal>
)
}
실장 후 정상적으로 동작한 것으로 판명되었습니다.여기서는 DOM 요소에 직접 modal component를 부가합니다.
export const Modal = ({children, onClose}: modelProps) => {
const modalDOM = document.getElementById("modal");
const close = (e: React.MouseEvent) => {
e.stopPropagation();
onClose();
};
return (
createPortal(
<div className="modal" onClick={close}>
<div className="modal__close-modal" onClick={close}>x</div>
{children}
</div>,
modalDOM || document.body)
)
}
보니 내가 바인딩하고 .this
이치노
혹시 다른 사람이 이런 문제가 생길까 봐 여기에 올려야겠다고 생각했어요
난 바꿔야 했다.
<Field
label="Post Content"
name="text"
component={this.renderField.bind(this)}
/>
로.
<Field
label="Post Content"
name="text"
component={this.renderField}
/>
에는 사실 때문에 입니다.this
renderField
하지만 제가 이 글을 올리면 다른 사람에게 도움이 될 거예요.
일부 컨트롤 입력의 텍스트를 변경하면 부모 컨트롤이 (소품과의 바인딩에 따라) 재렌더링될 수 있습니다.이 경우 포커스가 손실됩니다.편집은 DOM의 상위 컨테이너에 영향을 주지 않아야 합니다.
언급URL : https://stackoverflow.com/questions/22573494/react-js-input-losing-focus-when-rerendering
'programing' 카테고리의 다른 글
[객체]에서 "객체"를 두 번 언급하는 이유는 무엇입니까? (0) | 2023.03.18 |
---|---|
스프링 부트 단일 페이지 응용 프로그램 - 모든 요청을 index.html로 전송합니다. (0) | 2023.03.18 |
ORA-38104: ON 절에서 참조되는 열은 업데이트할 수 없습니다. (0) | 2023.03.18 |
woocommerce 함수로 작성된 함수를 덮어쓰려고 합니다.php 파일 (0) | 2023.03.18 |
단일 스프링 부트 테스트 속성 재정의 (0) | 2023.03.18 |