javascript - 更改事件与 React 和 Typescript 混为一谈
问题描述
我用 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;
名字到输入字段的绑定通常有效,但不适用于第一次触发的更改事件。第一个更改事件在触发时获得一个空值,并且名字将被设置为一个空字符串。所有其他更改事件似乎都有效。如您所见,我正在使用 TypeScript,并希望尽可能地保持类型安全......
也许与事件绑定混在一起。非常欢迎任何帮助!
该应用程序如下所示: React app with event binding
解决方案
事件绑定确实是这里的问题。为了使它工作,我必须将处理程序方法的调用(在渲染方法中)更改为:
<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>) => {...}
有关部分绑定的文档可在以下位置找到:
推荐阅读
- html - 需要使用 css flexbox 制作 row-column-row
- django - 如何在 SerializerMethodField 修改值后应用 django-filter?
- java - 如果使用到进程结束,是否需要关闭资源?
- binary-search-tree - 这些频率的最佳二进制代码是否明确?
- python - 在 Python 中将用户输入导出到 txt 文件时遇到问题
- amazon-web-services - AWS Application Load Balancer 向不健康的目标组/实例发送请求
- javascript - 如何在javascript中的列内创建一个包含对象数组的二维数组?
- javascript - requestAnimationFrame 在添加/删除 DOM 元素时是否带来优势?
- go - 所有的 goroutine 都是休眠死锁
- c# - 如何从 Marten 构建的事件存储中获取特定类型的聚合集合?