javascript - 无法输入反应输入字段
问题描述
目前,我的输入字段的默认值为 1。如果我尝试在输入字段中输入内容,则不会发生任何变化。
interface Orders {
order_graph_1: number;
order_graph_2: number;
}
interface MyProps extends Orders {
setOrders: (...args: any) => void; // function which takes args...??
}
interface MyState extends Orders {
//otherProperty: string;
}
class Setup extends React.Component<MyProps, MyState>{
state = {
order_graph_1: this.props.order_graph_1,
order_graph_2: this.props.order_graph_2
};
// needs to be an arrow function to access `this` properly
// could use ( event: React.ChangeEvent<HTMLInputElement>)
// could avoid the assertion by passing the name as an argument
setOrders = (event: any) => {
this.setState((prevState) => ({
...prevState,
[event.target.name]: parseInt(event.target.value)
}));
};
render(){
return(
<div className="row">
<div className="col-6">
<p className="text-center">Order of first model: </p>
<div className="w-100 d-flex justify-content-center">
<input className="text-center" name="order_graph_1" type="number" value={this.props.order_graph_1} onChange={this.setOrders.bind(this)} min="1" max="10"/>
</div>
</div>
</div>
);
}
}
export default Setup;
为了测试,我取消了 onChange 函数
onChange={()=>console.log("hello")}
每次我尝试在输入字段中输入时,我都看到控制台中打印了 hello,但输入字段的值仍然没有改变。
编辑:
这是一个 JS 代码(https://github.com/MenesesGHZ/polynomial-regression-js):
class RegressionSetup extends React.Component{
constructor(props){
super(props);
this.orders = {
"order_graph_1":this.props.order_graph_1,
"order_graph_2":this.props.order_graph_2
};
}
setOrders(event){
this.orders[event.target.name] = parseInt(event.target.value);
this.props.setOrders(Object.values(this.orders));
}
render(){
return(
<div className="row">
<div className="col-6">
<p className="text-center">Order of first model: </p>
<div className="w-100 d-flex justify-content-center">
<input className="text-center" name="order_graph_1" type="number" value={this.props.order_graph_1} onChange={this.setOrders.bind(this)} min="1" max="10"/>
</div>
</div>
<div className="col-6">
<p className="text-center">Order of second model: </p>
<div className="w-100 d-flex justify-content-center">
<input className="text-center"name="order_graph_2" type="number" value={this.props.order_graph_2} onChange={this.setOrders.bind(this)} min="1" max="10"/>
</div>
</div>
</div>
);
}
}
export default RegressionSetup;
更改输入值后,图表上的一条线会根据该值更改。我不得不将此代码更改为 Typescript。这就是我现在所拥有的。
interface Orders {
order_graph_1: number;
order_graph_2: number;
}
interface MyProps extends Orders {
setOrders: (...args: any) => void; // function which takes args...??
}
interface MyState extends Orders {
//otherProperty: string;
}
class Setup extends React.Component<MyProps, MyState>{
state = {
// it is best not to derive state from props
order_graph_1: this.props.order_graph_1,
order_graph_2: this.props.order_graph_2
};
// needs to be an arrow function to access `this` properly
// could use ( event: React.ChangeEvent<HTMLInputElement>)
// could avoid the assertion by passing the name as an argument
setOrders = (event: any) => {
// I don't love this solution, but we can avoid the TS errors by copying the previous state
this.setState((prevState) => ({
...prevState,
[event.target.name]: parseInt(event.target.value)
}));
};
render(){
return(
<div className="row">
<div className="col-6">
<p className="text-center">Order of first model: </p>
<div className="w-100 d-flex justify-content-center">
<input className="text-center" name="order_graph_1" type="number" value={this.state.order_graph_1} onChange={this.setOrders.bind(this)} min="1" max="10"/>
</div>
</div>
{/* <div className="col-6">
<p className="text-center">Order of second model: </p>
<div className="w-100 d-flex justify-content-center">
<input className="text-center"name="order_graph_2" type="number" value={this.props.order_graph_2} onChange={this.setOrders.bind(this)} min="1" max="10"/>
</div>
</div> */}
</div>
);
}
}
export default Setup;
虽然它编译没有错误,但输入值的东西不起作用。它不会改变图表上的线条,所以我假设状态没有保存。我怎样才能解决这个问题?
解决方案
问题是您使用的是从道具中获得的值,order_graph_1
但order_graph_2
更新了您在状态中的值,而不是更新道具中的值。
您正在转换的代码会更新状态和道具(通过调用this.props.setOrders
)。但是完全没有必要让这些变量处于组件状态,RegressionSetup
因为它已经可以通过 props 访问和更新它们。
从父setOrders
组件向下传递的函数也有点傻,因为两个组件都有一个带有属性的状态,那么为什么我们将它们作为一个元组传递给? Main
order_graph_1
order_graph_2
setOrders
您可以在其中Main
删除该setOrders
函数,而是向下传递一个调用setState
.
<RegressionSetup
order_graph_1={this.state.order_graph_1}
order_graph_2={this.state.order_graph_2}
setOrders={(orders) => this.setState(orders)}
/>
setState
在类组件中采用部分新状态并将其与当前状态合并。这意味着我们甚至不必将两个订单都传递给setOrders
. 我们只需一个订单就可以调用它,这很好。
所以我们可以RegressionComponent
像这样定义道具:
export interface OrderGraphs {
order_graph_1: number;
order_graph_2: number;
}
interface Props extends OrderGraphs {
setOrders(graphs: Partial<OrderGraphs>): void;
}
它没有理由成为类组件,但这也没关系。 RegressionSetup
不需要使用状态、钩子或生命周期方法。它只需要 props 并返回 JSX。
我仍然更喜欢使用函数来呈现两个输入,因为它的重复性更少,但显然你不必这样做。我们使用该变量property
从 props 中获取正确的属性,value={this.props[property]}
并在我们传递给的对象上设置正确的键setOrders
:onChange={(e) => this.props.setOrders({[property]: parseInt(e.target.value, 10)})}
class RegressionSetup extends React.Component<Props> {
renderInput(property: keyof OrderGraphs, label: string) {
return (
<div className="col-6">
<p className="text-center">{label}</p>
<div className="w-100 d-flex justify-content-center">
<input
className="text-center"
name={property}
type="number"
value={this.props[property]}
onChange={(e) =>
this.props.setOrders({ [property]: parseInt(e.target.value, 10) })
}
min="1"
max="10"
step="1"
/>
</div>
</div>
);
}
render() {
return (
<div className="row">
{this.renderInput("order_graph_1", "Order of first model: ")}
{this.renderInput("order_graph_2", "Order of second model: ")}
</div>
);
}
}
我也弄乱了其他组件。我为所有内容添加Props
和State
类型。我还使用箭头函数来摆脱所有的bind(this)
调用。仍然有一些与外部包(chart.js 和 mathjs)相关的 Typescript 错误。
推荐阅读
- c# - 服务堆栈 [必需] 注释不起作用
- node.js - 如何在 Heroku 上部署 NodeJs、Socket 应用程序而不会出现任何错误?
- gradle - 找不到 Gradle 子模块
- linux - 带有连字符和空格的 grep 正则表达式
- recursion - 在 ASM 和 LC3 中使用堆栈进行递归编程
- php - 将字符串从 ISO-8859-1 转换为 UTF8
- php - 按钮重定向到 php 文件
- ios - RxDataSources itemDeselected 没有被调用
- c# - 如何使用 SqlDataReader 返回和使用 IAsyncEnumerable
- javascript - 如何仅在按下键后运行我的功能?