React待办事项应用空白任务验证实现咨询
Hey there! No worries at all—adding validation to block empty tasks is a simple and essential tweak for your app. Let's break down exactly how to implement it, step by step.
Core Approach
The key idea is to check if the input value is empty (or just whitespace) before allowing a new task to be added. We'll modify your handleSubmit function to handle this check, and optionally add a user-friendly error message to explain why the task wasn't added.
Step 1: Update the handleSubmit Function
First, let's modify the submission logic to validate the input. We'll use trim() to remove leading/trailing whitespace (so users can't add tasks that are just spaces):
handleSubmit = (evt) => { if (evt.keyCode === 13) { // Remove leading/trailing whitespace from the input const trimmedTask = this.state.inputValue.trim(); // If the trimmed value is empty, exit early (don't add the task) if (!trimmedTask) { // Optional: Set an error message to show the user this.setState({ errorMessage: "Please enter a task!" }); return; } // Clear any existing error message since input is valid this.setState({ errorMessage: "" }); // Proceed to add the valid task const newTodo = { value: trimmedTask, done: false }; const todos = this.state.todos.concat(newTodo); this.setState({ todos: todos, inputValue: "" }); } };
Step 2: Add an Error State (Optional but Recommended)
To make the validation more user-friendly, add an errorMessage property to your component's state to display feedback when the user tries to add an empty task:
state = { query: "", inputValue: "", todos: [ { value: "Naumiej się Reacta", done: false }, { value: "Pucuj trzewiki ", done: true }, ], direction: "row", justify: "left", alignItems: "left", errorMessage: "", // New state for error feedback };
Step 3: Display the Error Message in Your Render
Add a small error message below your "Add Task" input to show the validation feedback:
render() { return ( <Grid item xs={12} style={{ padding: 30, display: "flex" }}> <div className="App"> <Typography type="body1'" color="inherit" text-align="left"> <AppBar position="static" color="default" style={{ flexDirection: "center" }}> <Toolbar> <TextField style={{ float: "left", paddingRight: 40 }} placeholder="Add Task ..." onChange={this.handleChange} inputValue={this.state.inputValue} onKeyDown={this.handleSubmit} /> {/* Display error message if it exists */} {this.state.errorMessage && ( <Typography color="error" variant="body2" style={{ marginTop: 8 }}> {this.state.errorMessage} </Typography> )} <TextField type="text" placeholder="Search..." onChange={this.searchChanged} /> </Toolbar> </AppBar> </Typography> <Paper> <List style={{ marginTop: 90 }} removeMe={this.removeMe} todos={this.state.todos} query={this.state.query} /> </Paper> </div> </Grid> ); }
Full Modified Code
Here's the complete updated component with all the validation changes:
import React, { Component } from 'react'; import AppBar from 'material-ui/AppBar'; import Toolbar from 'material-ui/Toolbar'; import Typography from 'material-ui/Typography'; import Paper from 'material-ui/Paper'; import Grid from 'material-ui/Grid'; import TextField from 'material-ui/TextField'; import List from './List'; import '../App.css'; class App extends Component { state = { query: '', inputValue: '', todos: [ { value: 'Naumiej się Reacta', done: false }, { value: 'Pucuj trzewiki ', done: true }, ], direction: 'row', justify: 'left', alignItems: 'left', errorMessage: '', // Added error state } handleChange = (evt) => { this.setState({ inputValue: evt.target.value }); } removeMe = (index) => { this.setState({ todos: this.state.todos.filter((_, i) => i !== index) }) } searchChanged = (evt) => { this.setState({ query: evt.target.value }) } handleSubmit = (evt) => { if (evt.keyCode === 13) { const trimmedTask = this.state.inputValue.trim(); if (!trimmedTask) { this.setState({ errorMessage: "Please enter a task!" }); return; } this.setState({ errorMessage: "" }); const newTodo = { value: trimmedTask, done: false }; const todos = this.state.todos.concat(newTodo); this.setState({ todos: todos, inputValue: '' }) } } render() { return ( <Grid item xs={12} style={{ padding: 30, display: 'flex' }}> <div className="App"> <Typography type="body1'" color="inherit" text-align='left'> <AppBar position="static" color="default" style={{ flexDirection: 'center' }}> <Toolbar> <TextField style={{ float: 'left', paddingRight: 40, }} placeholder="Add Task ..." onChange={this.handleChange} inputValue={this.state.inputValue} onKeyDown={this.handleSubmit} /> {/* Error message display */} {this.state.errorMessage && ( <Typography color="error" variant="body2" style={{ marginTop: 8 }}> {this.state.errorMessage} </Typography> )} <TextField type="text" placeholder="Search..." onChange={this.searchChanged} /> </Toolbar> </AppBar> </Typography> <Paper> <List style={{ marginTop: 90 }} removeMe={this.removeMe} todos={this.state.todos} query={this.state.query} /> </Paper> </div> </Grid> ); } } export default App;
Why This Works
trim()ensures that inputs with only spaces are treated as empty, preventing meaningless tasks from being added.- The early
returnstops the rest of the submission logic from running if the input is invalid. - The error message gives clear feedback to the user, so they understand why their task wasn't added.
内容的提问来源于stack exchange,提问作者Krzysztof Durak

