【问题标题】:React - not refresh page after post with error response反应 - 发布错误响应后不刷新页面
【发布时间】:2019-08-25 05:16:02
【问题描述】:

我有一个应用程序,它从服务器获取数据,它是用 nodeJS 编写的。 使用componentDidMount 我获取数据。在页面上输入带有数据的表格名称,并且每一行都有复选框。当我单击“发送”按钮时,选定的行将在后端发送。在后端,我验证唯一名称。如果不是,我返回错误。但是fronted每次都会刷新。并且不可能得到错误信息。

import React, {Component} from 'react';
import axios from 'axios';
import MyNavbar from "./MyNavbar";

class Offer extends Component {
    constructor(props) {
        super(props);
        this.handleSubmit = this.handleSubmit.bind(this);
        this.handleCheckedOrder = this.handleCheckedOrder.bind(this);
        this.state = {
            offers: [],
            name: '',
            selectedFoods: [],
            selectedBuild: 'Nevybráno',
            isOrderChecked: false
        };
    }

    componentDidMount() {
        this.getOffer();
    }

    getOffer() {
        const url = '/offer';
        axios.get(url).then(response => {
            this.setState({offers: response.data})
        }).catch(() => 'Cannot load menu');
    };

    handleNameChange = evt => {
        this.setState({name: evt.target.value});
    };

    handleChecboxChange = offer => {
        if (this.state.selectedFoods.includes(offer)) {
            this.setState({selectedFoods: this.state.selectedFoods.filter(item => item !== offer)});
        } else {
            this.setState({selectedFoods: [...this.state.selectedFoods, offer]});
        }
    };

    handleCheckedOrder() {
        this.setState({isChecked: !this.state.isChecked});
    }

    isValid() {
        let isEnabledSubmit = this.state.name.length > 0;
        let isSelectedFoodAndNotOnlySoap = this.state.selectedFoods.length > 0 && this.state.selectedFoods.some(food => food.index !== 0);
        let isSelectedBuild = this.state.selectedBuild !== 'Nevybráno';
        return isEnabledSubmit && isSelectedFoodAndNotOnlySoap && isSelectedBuild;
    }

    handleSubmit() {
        axios({
            method: 'post',
            url: '/order',
            headers: {},
            data: {
                name: this.state.name,
                food: this.state.selectedFoods,
                order: this.state.isChecked,
                build: this.state.selectedBuild
            }
        });
    };

    render() {
        const {offers} = this.state;
        const options = ["Nevybráno", "A", "B"];

        return (
            <div>
                <MyNavbar/>
                <div className="container">
                    <form className="form-inline justify-content-center" onSubmit={this.handleSubmit}>
                        <table className="table">
                            <tbody>
                            <tr>
                                <th>&nbsp;</th>
                                <th>#</th>
                                <th>Váha</th>
                                <th>Menu</th>
                                <th>Cena</th>
                            </tr>
                            {offers.map((offer) => {
                                return (
                                    <tr key={offer.index}>
                                        <td style={{width: '5%'}}>
                                            <input type="checkbox" className="checkbox"
                                                   onChange={this.handleChecboxChange.bind(this, offer)}/>
                                        </td>
                                        <td style={{width: '5%'}}>{offer.index}</td>
                                        <td style={{width: '10%'}}>{offer.weight}g</td>
                                        <td style={{width: '70%'}}>{offer.name}</td>
                                        <td style={{width: '20%'}}>{offer.discount} Kč</td>
                                    </tr>
                                )
                            })}
                            </tbody>
                        </table>

                        <label className="sr-only" htmlFor="inlineFormInput">Name</label>
                        <input type="text" className="form-control mb-2 mr-sm-2 mb-sm-0" id="inlineFormInput"
                               placeholder="Jméno" onChange={this.handleNameChange}/>

                        <label className="mr-sm-2" htmlFor="inlineFormCustomSelect">Budova</label>
                        <select className="custom-select mb-2 mr-sm-2 mb-sm-0" id="inlineFormCustomSelect"
                                onChange={(e) => this.setState({selectedBuild: e.target.value})}>
                            {options.map(option => {
                                return <option value={option} key={option}>{option}</option>
                            })}
                        </select>

                        <div className="form-check mb-2 mr-sm-2 mb-sm-0">
                            <label className="form-check-label">
                                <input className="form-check-input" type="checkbox"
                                       onChange={this.handleCheckedOrder}/> Objednám
                            </label>
                        </div>

                        <button type="submit" className="btn btn-secondary"
                                disabled={!this.isValid()}>Odeslat
                        </button>
                    </form>
                </div>
            </div>
        );
    }
}

export default Offer;

【问题讨论】:

    标签: javascript reactjs


    【解决方案1】:

    这是因为按钮默认提交表单并刷新页面。这可以通过使用evt.preventDefault();来防止

    handleSubmit(evt) {
        evt.preventDefault();
        axios({
            method: 'post',
            url: '/order',
            headers: {},
            data: {
                name: this.state.name,
                food: this.state.selectedFoods,
                order: this.state.isChecked,
                build: this.state.selectedBuild
            }
        });
    };
    

    【讨论】:

      【解决方案2】:

      除了maartendev's 注释之外,要获取错误并导致组件状态,您可以将处理程序编写为:

      handleSubmit(evt) {
        evt.preventDefault();
        axios({
          method: 'post',
          url: '/order',
          headers: {},
          data: {
              name: this.state.name,
              food: this.state.selectedFoods,
              order: this.state.isChecked,
              build: this.state.selectedBuild
          }
         }).catch(({ response }) => this.setState({ errors: response.data }));
      }
      

      这将在 this.state.errors 中为您提供可用于 render 方法的错误。

      【讨论】:

        【解决方案3】:

        尝试在表单提交function evt.preventDefault();}中添加

        handleSubmit=(eve)=>
        {
          evt.preventDefault();
        }
        

        告诉我它是否有效。

        【讨论】:

        • 我改进了您的代码格式,但我感觉它可能不完整。所以请修正任何不一致的地方,让这个答案有帮助。
        猜你喜欢
        • 1970-01-01
        • 2014-06-19
        • 1970-01-01
        • 2020-07-13
        • 1970-01-01
        • 2021-03-16
        • 2018-02-15
        • 1970-01-01
        • 2021-11-02
        相关资源
        最近更新 更多