我正在尝试制作一个表单,在其中我可以输入游戏的三个值(标题,等级和价格),并将这些值保存在提交中并在表格下方显示列表。我是新来的人,可以通过使用ref来使其工作,但我不确定这是否是最佳实践。在搜寻解决方案时,我看到许多人使用onChange来保存状态,因为即使有一个提交按钮,它也可以被键入。这是我所做的,但是我不确定这是否是最佳做法。我可以得到一些反馈吗?谢谢!
类应用扩展了组件{
state = {
games: [{title:"Mario Kart", rating:7.4,price:"$45"}]
};
handleSubmitButton = (e) => {
e.preventDefault();
this.setState(prevState => ({
games: [...prevState.games, {
title: this.refs.title.value,
rating: this.refs.rating.value,
price: this.refs.price.value
}]
}));
}
render () {
return (
<div>
<form onSubmit={this.handleSubmitButton}>
<label>
Game Name
<input type="text" id="name-input" ref="title"/>
</label>
<label>
Rating
<input type="text" id="ratings-input" ref="rating"/>
</label>
<label>
Price
<input type="text" id="price-input" ref="price"/>
</label>
<button type="submit" id="submit-button">Submit</button>
</form>
<label>
Search
<input type="text" id="search-input"/>
</label>
<table id="directory-table">
<tr>
<th>Name</th>
<th>Ratings</th>
<th>Duration</th>
</tr>
{this.state.games.map(game => {
return (
<tr>
<th>{game.title}</th>
<th>{game.rating}</th>
<th>{game.price}</th>
</tr>
)
})}
</table>
</div>
);
} }
答案 0 :(得分:1)
我认为,正如您提到的,首选方法是使用onChange更新每个受控输入的状态,然后将输入的值设置为您状态中的value。然后,一旦您点击了提交,就会触发一个函数,该函数可以在将值发布到端点之前验证输入内容。
在您的示例中,您可以在每个输入有效并在表输出中用作条件后,在状态中设置一个布尔值:
{this.state.formValid && this.state.games.map(games => ...
实现此目标的一种方法是,您可以使用onChange处理程序将当前值推送到临时状态插槽中,说您的输入的ID为“ title”,然后使用this.setState({ [event.target.id]: event.target.value })
然后在您的提交处理程序中从这些临时值构建一个对象以放入您的游戏数组,最后清除状态下的标题,等级和价格值?
这是我的意思的一个垃圾示例,尽管我使用钩子完成了该操作,并且对useState值进行了一些重复,例如,使用useReducer可以更好地做到这一点:https://codesandbox.io/s/peaceful-moore-jrjpg
答案 1 :(得分:1)
尝试将“受控组件”用作输入,并且还建议使用解构。 您可以在此处了解有关受控组件的信息 https://www.robinwieruch.de/react-controlled-components/ 还阅读了有关列表和键的信息,因为在将值映射到打印表行https://reactjs.org/docs/lists-and-keys.html
时出错尝试以下代码
import React, { Component } from 'react';
import './App.css';
class App extends Component {
state = {
title: "",
rating: "",
price: "",
games: [{ title: "Mario Kart", rating: 7.4, price: "$45" }]
};
handleSubmitButton = (e) => {
e.preventDefault();
const { title, rating, price } = this.state;
this.setState(prevState => ({
games: [...prevState.games, { title, rating, price }]
}));
}
handleChange = (evt) => {
console.log(evt.target)
this.setState({ [evt.target.name]: evt.target.value });
}
render() {
const { title, rating, price } = this.state
return (
<div>
<form onSubmit={this.handleSubmitButton}>
<label>
Game Name
<input
type="text"
id="name-input"
name="title"
value={title}
onChange={(evt) => this.handleChange(evt)}
/>
</label>
<label>
Rating
<input
type="text"
id="ratings-input"
name="rating"
value={rating}
onChange={(evt) => this.handleChange(evt)}
/>
</label>
<label>
Price
<input
type="text"
id="price-input"
name="price"
value={price}
onChange={(evt) => this.handleChange(evt)}
/>
</label>
<button type="submit" id="submit-button">Submit</button>
</form>
<label>
Search
<input type="text"
id="search-input" />
</label>
<table id="directory-table">
<tbody>
<tr>
<th>Name</th>
<th>Ratings</th>
<th>Duration</th>
</tr>
{this.state.games.map((game,index) => {
return (
<tr key={index}>
<th>{game.title}</th>
<th>{game.rating}</th>
<th>{game.price}</th>
</tr>
)
})}
</tbody>
</table>
</div>
);
}
}
export default App;