javascript - React.js - input mister fokus ved gjengivelse på nytt
Jeg skriver bare til tekstfeltet, og i onChange-hendelsen kaller jeg setState, så React render om brukergrensesnittet mitt. Problemet er at tekstfeltet alltid mister fokus, så jeg må fokusere det igjen for hver bokstav :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>
);
}
});
Svar #1
Uten å se resten av koden din, er dette et gjetning. Når du oppretter en EditorContainer, spesifiser en unik nøkkel for komponenten:
<EditorContainer key="editor1"/>Når en ny gjengivelse skjer, hvis den samme nøkkelen sees, vil dette fortelle React å ikke overskrive og regenerere visningen, men heller gjenbruke den. Da bør det fokuserte elementet beholde fokus.
Svar #2
Jeg kommer stadig tilbake hit igjen og igjen og finner alltid løsningen på mitt et annet sted til slutt. Så jeg vil dokumentere det her fordi jeg vet at jeg vil glemme dette igjen!
Årsaken til at input mistet fokus i mitt tilfelle var på grunn av at jeg rendret input på nytt ved tilstandsforandring.
Feilaktig kode:
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>
)
}
}
Så problemet er at jeg alltid begynner å kode alt på ett sted for å raskt teste og senere dele det opp i separate moduler. Men her slår denne strategien tilbake fordi oppdatering av tilstanden ved inputendring utløser render-funksjonen og fokuset går tapt.
Løsningen er enkel, gjør moduleringen fra begynnelsen, med andre ord, "Flytt Input-komponenten ut av render-funksjonen"
Fikset kode
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>
)
}
}
Ref. til løsningen: https://github.com/styled-components/styled-components/issues/540#issuecomment-283664947
Svar #3
Jeg hadde de samme symptomene med hooks. Likevel var problemet mitt å definere en komponent inne i forelderen.
Feil :
const Parent =() => {
const Child = () => <p>Child!</p>
return <Child />
}
Høyre :
const Child = () => <p>Child!</p>
const Parent = () => <Child />
Svar #4
Hvis det er et problem innenfor en react-router <Route/> bruk render-egenskapen i stedet for component.
<Route path="/user" render={() => <UserPage/>} />
Tapet av fokus skjer fordi component-egenskapen bruker React.createElement hver gang i stedet for bare å rendre endringene på nytt.
Detaljer her: https://reacttraining.com/react-router/web/api/Route/component
Svar #5
Mitt svar ligner på det @z5h sa.
I mitt tilfelle brukte jeg Math.random() for å generere en unik key for komponenten.
Jeg trodde key bare brukes for å utløse en ny gjengivelse for den spesifikke komponenten, i stedet for å rendre alle komponentene i den arrayen (jeg returnerer en array av komponenter i koden min). Jeg visste ikke at den brukes for å gjenopprette tilstanden etter gjengivelse.
Å fjerne det gjorde susen for meg.
Svar #6
Det jeg gjorde var bare å endre value prop til defaultValue, og den andre endringen var onChange hendelsen til onBlur.
Svar #7
Å bruke autoFocus-attributtet på input-elementet kan fungere som en løsning i situasjoner der det bare er ett input som trenger å få fokus. I så fall ville et key-attributt være unødvendig fordi det bare er ett element, og dessuten ville du ikke trenge å bekymre deg for å bryte input-elementet ut i sin egen komponent for å unngå å miste fokus ved re-rendering av hovedkomponenten.
