我用TypeScript和React.js创建了一个简单的应用程序。我将create-react-app与--scripts-version = react-scripts-ts参数一起使用,并获得了可以正常使用的应用程序。
该应用程序现在只有2个组件:App.tsx,一个包含人员列表和Person.tsx的有状态组件,一个无状态功能组件,包含人员数据和名称输入文本。
这是 Person.tsx 的代码:
import * as React from "react";
export interface IPersonProps {
id: string;
firstname: string;
change: (event: React.ChangeEvent<HTMLInputElement>) => void;
}
export const Person: React.SFC<IPersonProps> = props => {
return (
<div>
<h1>
Hi {props.firstname}
</h1>
<input type="text" onChange={props.change} value={props.firstname} />
</div>
);
};
这是 App.tsx 的代码:
import * as React from "react";
import "./App.css";
import { Person, IPersonProps } from "./Person";
interface IAppState {
persons: Array<IPersonProps>,
showPersons: boolean;
}
class App extends React.Component<{}, IAppState> {
readonly togglePersonsHandler = () => {
const show = this.state.showPersons;
this.setState({showPersons: !show});
}
readonly firstnameChangeHandler = (event:React.ChangeEvent<HTMLInputElement>,
personId: string) => {
const personIndex = this.state.persons.findIndex(person => {
return person.id === personId;
});
const person = {
...this.state.persons[personIndex]
}
person.firstname = event.target.value;
const persons = [...this.state.persons];
persons[personIndex] = person;
this.setState({
persons: persons
} as IAppState);
}
constructor(props: any, state: IAppState) {
super(props, state);
this.state = {
persons: [
{ id: 'a', firstname: "Michael" } as IPersonProps,
{ id: 'b', firstname: "Mel"} as IPersonProps
],
showPersons: false
};
}
public render() {
let persons = null;
if (this.state.showPersons) {
persons = (
<div>
{
this.state.persons.map((person, index) => {
return <Person
id={person.id}
firstname={person.firstname}
key={person.id}
change={this.firstnameChangeHandler.bind(this, event, person.id)} />
})
}
</div>
)
}
return (
<div className="App">
<h1>React</h1>
<button onClick={this.togglePersonsHandler}>Toggle Persons</button>
{persons}
</div>
);
}
}
export default App;
通常将名字绑定到输入字段,但不适用于第一个触发的更改事件。触发时,第一个change事件将获得一个空值,并且名字将被设置为一个空字符串。所有其他更改事件似乎都起作用。如您所见,我正在使用TypeScript,并且希望尽可能地保持类型安全...
也许与事件绑定混为一谈。任何帮助都非常欢迎!
该应用程序如下所示: React app with event binding
答案 0 :(得分:1)
事件绑定确实是这里的问题。为了使其正常工作,我必须将处理程序方法(在render方法中)的调用更改为:
<Person
id={person.id}
firstname={person.firstname}
key={person.id}
change={this.firstnameChangeHandler.bind(null, person.id)} />
处理程序方法必须将其签名更改为
readonly firstnameChangeHandler = (personId: string, event:React.ChangeEvent<HTMLInputElement>) => {...}
有关部分绑定的文档可以在以下位置找到: