我有3个组件,其中第一个在输入字段上发生变化会使它失去焦点。我试着给输入字段和divs键,但不能解决我的问题。我是React的新手,所以我可能在做一些基本的错误操作。我没有在render方法中创建新函数,这是大多数在stackoverflow中记录的焦点问题的原因。因此,发布新帖子的原因。
Index.tsx
import * as React from "react";
import { IQuery, Queries } from "./components/Queries/Queries";
interface IManageResponseState {
primaryQuery: IQuery;
alternateQueries: IQuery[];
}
export class ManageResponse extends React.Component<any, IManageResponseState> {
constructor(props: any) {
super(props);
this.state = {
primaryQuery: {
queryText: "This is my primary query text",
id: 0
}, alternateQueries: [{
queryText: "this is my alternate query text 1",
id: 1
},
{
queryText: "this is my alternate query text 2",
id: 2
}]
};
this.addFunc = this.addFunc.bind(this);
this.removeFunc = this.removeFunc.bind(this);
this.primaryChangedFunc = this.primaryChangedFunc.bind(this);
this.alternateChangedFunc = this.alternateChangedFunc.bind(this);
}
public addFunc(text: string) {
const newQueries = this.state.alternateQueries.filter(q => true);
newQueries.push({ id: 0, queryText: text });
this.setState({ alternateQueries: newQueries });
};
public removeFunc(index: number) {
this.setState({ alternateQueries: this.state.alternateQueries.splice(index, 1) });
console.log("Remove called:" + index);
};
public primaryChangedFunc(text: string) {
const query = {
queryText: text,
id: 0
};
this.setState({ primaryQuery: query });
console.log("changed primary called:" + text);
}
public alternateChangedFunc(index: number, text: string) {
const item = this.state.alternateQueries[index];
const newQueries = this.state.alternateQueries.filter(q => true);
newQueries[index] = {
queryText: text,
id: item.id
};
this.setState({ alternateQueries: newQueries })
console.log("changed alternate called:" + text);
}
public render() {
return (
<React.Fragment>
<Queries primaryQuery={this.state.primaryQuery} alternateQueries={this.state.alternateQueries} onAddQuery={this.addFunc} onRemoveQuery={this.removeFunc} onPrimaryChanged={this.primaryChangedFunc} onAlternateQueryChanged={this.alternateChangedFunc} />
</React.Fragment>
);
}
}
Queries.tsx
import * as classnames from 'classnames';
import * as React from "react";
import { AlternateQueryItem } from "../AlternateQueryItem/AlternateQueryItem";
import './Queries.scss'
export interface IQuery {
queryText: string;
id: number;
}
export interface IQueryProps {
primaryQuery: IQuery;
alternateQueries: IQuery[];
onPrimaryChanged: (queryText: string) => void;
onAlternateQueryChanged: (index: number, queryText: string) => void;
onAddQuery: (queryText: string) => void;
onRemoveQuery: (atIndex: number) => void;
}
interface IQueryState {
primaryQueryInvalid: boolean;
}
class Queries extends React.Component<IQueryProps, IQueryState> {
constructor(props: IQueryProps) {
super(props);
this.onPrimaryQueryChanged = this.onPrimaryQueryChanged.bind(this);
this.state = { primaryQueryInvalid: false };
}
public render() {
return (
<main className="query-main-container">
<div className="primary-query-container">
<div className="form-group">
<h5 className={classnames("primary-query-header", { 'invalid': this.state.primaryQueryInvalid })}>Primary query</h5>
<div className="primary-query">
<div>{ "hello " + this.state.primaryQueryInvalid }</div>
<input type="text" value={this.props.primaryQuery.queryText} onChange={this.onPrimaryQueryChanged} className="form-control"/>
</div>
</div>
</div>
<div>
<h5 className="query-header">Query variations</h5>
<hr />
</div>
<div className="query-container">
{this.props.alternateQueries && this.props.alternateQueries.map((q, i) => this.renderQuery(q, i))}
</div>
</main>
);
}
public renderQuery(query: IQuery, key: number) {
return (
<AlternateQueryItem onChanged={this.props.onAlternateQueryChanged} query={query} key={key} index={key} />
);
}
private onPrimaryQueryChanged = (ev: React.FormEvent<HTMLInputElement>) => {
this.setState({ primaryQueryInvalid: ev.currentTarget.value === ""})
this.props.onPrimaryChanged(ev.currentTarget.value)
}
}
export { Queries };
AlternateQueryItem.tsx
import * as React from "react";
import { IQuery } from "../Queries/Queries";
export interface IAlternateQueryProps {
query: IQuery;
onChanged: (index: number, queryText: string) => void;
index: number;
}
class AlternateQueryItem extends React.Component<IAlternateQueryProps> {
constructor(props: IAlternateQueryProps) {
super(props);
this.onItemChanged = this.onItemChanged.bind(this);
}
public render() {
return (
<div className="form-group">
<div className="alternate-query">
<input type="text" value={this.props.query.queryText} onChange={this.onItemChanged} className="form-control" />
</div>
</div>
);
}
public onItemChanged = (ev: any) => {
this.props.onChanged(this.props.index, ev.currentTarget.value)
}
}
export { AlternateQueryItem };