首页 > 解决方案 > 反应:为什么我的 id 未定义?axios.post 请求删除数据而不是更新

问题描述

感谢社区,我解决了 axios.get 的动态 ID 问题,${this.props.match.params.id}我可以访问每个产品的编辑表单。

不幸的是,这个技巧对于发布请求似乎效率低下,我被卡住了。当我提交我的表单时axios.post,我handleSubmit会删除我以前的数据,而不是用新的数据进行更新。我可以看到 sql 请求有未定义的数据,尤其是id,我不明白为什么..

我是 React 的新手,所以你能建议我如何修复我的帖子请求。

我为您提供了我的编辑表单,并且返回的一些节点可能是相关的。

编辑表格

import React, { Component } from 'react';
import { withRouter } from 'react-router';
import axios from 'axios';

import Navbar from 'react-bootstrap/Navbar';
import Nav from 'react-bootstrap/Nav';
import Form from 'react-bootstrap/Form';
import Col from 'react-bootstrap/Col';
import FormControl from 'react-bootstrap/FormControl';
import Button from 'react-bootstrap/Button';

class EditForm extends React.Component {

    constructor(props) {
        super(props);
        this.state = { product: [] };
        this.handleChange = this.handleChange.bind(this);
        this.handleSubmit = this.handleSubmit.bind(this);
    };
    
    componentDidMount = () => {
        axios
        .get(`/products/edit-form/${this.props.match.params.id}`)
        .then(response => {
            console.log(response.data.products);
            this.setState({
                product: response.data.products
            })
        });    
    };

    handleChange(e) {
        this.setState({id: e.target.value})
        this.setState({reference: e.target.value})
        this.setState({designation: e.target.value})        
    }

     handleSubmit(e) {
        e.preventDefault();   
        const data = { 
        id: this.state.id,
        reference: this.state.reference,
        designation: this.state.designation        
        }  

        axios
        .post(`/products/${data.id}`, data )
        .then(res => console.log(res))      
        .catch(err => console.log(err));
    };
 
    renderForm() {
        return this.state.product.map((product, index) => {
            const { id,reference,designation } = product
        return(
            <>         
            <Form className="post" onSubmit={this.handleSubmit}>
                <Form.Row>
                    <Form.Group as={Col} controlId="formGridReference">
                    <Form.Label>Reference</Form.Label>
                    <Form.Control type="text" value={reference} 
                        onChange={this.handleChange} name="reference"  />
                    </Form.Group>

                    <Form.Group as={Col} controlId="formGridDesignation">
                    <Form.Label>Designation</Form.Label>
                    <Form.Control type="text" value={designation} 
                        onChange={this.handleChange} name="designation"  />
                    </Form.Group>
                </Form.Row>                

                <Button variant="primary" type="submit">
                    Submit
                </Button>
            </Form>
            </>
            );
        })
    }
    
    render() {
        return (
            <div>
                <h1>Formulaire de modification</h1>
                {this.renderForm()}
            </div>        
        );
    }
}

export default withRouter(EditForm);

产品

import React, { Component } from 'react';
import Table from 'react-bootstrap/Table';
import Button from 'react-bootstrap/Button';
import { Link } from 'react-router-dom';
import axios from 'axios';

const headings = [
    'id','reference','designation'
];

export default class Products extends Component {

    constructor(props) {
        super(props);
        this.state = {
            products: []
        };
    };

    componentDidMount = () => {
        axios.get("/products").then(response => {
            console.log(response.data.products);
            this.setState({
                products: response.data.products
            })
        });
    };
 
    renderTableHeader() {       
        return headings.map((key, index) => {
        return <th key={index}>{key.toUpperCase()}</th>
        })
    } 

    renderProductData() {
        return this.state.products.map((product, index) => {
            const { id,reference,designation } = product
            return (
                <tr key={id}>
                    <td>
                        {id}
                        <Link to={`/edit-form/${id}`}>Modifier</Link>
                    </td>
                    <td>{reference}</td>
                    <td>{designation}</td>                               
                </tr>
            )
        })
    }
 
    render() {
        return (
            <div>
                <h1 id='title'>Produits</h1>
                <Table striped bordered hover id='products'>
                    <thead>
                        {this.renderTableHeader()}
                    </thead>
                    <tbody>
                        {this.renderProductData()}
                    </tbody>
                </Table>
            </div>
        );
    }
}

应用程序.js

class App extends Component {
    render() {
        return (
            <React.Fragment>
                <NavBar />            
                <Router>
                    <Route exact path="/" component={Products}/>
                    <Route path="/edit-form/:id" component={EditForm}/>
                </Router>
            </React.Fragment>  
        );
    }
}

节点后端

//routes.js

    // Get All
    router.get('/products', getProducts.getProducts);
    // Get sorted
    // router.get('/products/:param', getProducts.getProductsSorted);
    // Get single
    router.get('/products/edit-form/:productId', getProducts.getProduct);
    // Update
    router.post('/products/:productId', getProducts.postProduct);


// productController.js

const getProduct = async (req, res) => 
{
    const { productId } = req.params;
    const product = await productDb.getProduct(productId);
    res.status(200).send({ products: product.rows });    
};

const postProduct = async (req, res) => 
{
    const { productId } = req.params;
    const { reference,designation } = req.body;
    await productDb.updateProduct(productId, reference, designation);
    res.status(200).send(`Le produit reference ${reference} a été modifié`);  
    console.log(`Le produit reference ${reference} a été modifié`); 


// productDb.js

const getProduct = async (id) =>
{
    const connection = new DbConnection();
    return await connection.performQuery(`SELECT * FROM produits WHERE id=${id}`);
};

const updateProduct = async (id, reference, designation) =>
{
    const connection = new DbConnection();
    await connection.performQuery("UPDATE produits SET reference=?, designation=? WHERE id=?", 
    [reference, designation, id]);
};

谢谢

标签: javascriptnode.jsreactjspostaxios

解决方案


我会考虑检查状态:

 axios
        .get(`/products/edit-form/${this.props.match.params.id}`)
        .then(response => {
            console.log(response.data.products);
            this.setState({
                product: response.data.products
            })
        });   

这设置product为一系列产品

handleChange(e) {
        this.setState({id: e.target.value})
        this.setState({reference: e.target.value})
        this.setState({designation: e.target.value})        
    }

这会设置状态id, reference, designation- 但请注意它从相同的目标值读取 - 因此,如果参考文本字段发生更改,它将根据 @Asutosh 的评论将 id 和 designation 更改为相同的值。

 handleSubmit(e) {
        e.preventDefault();     
        const data = { 
        id: this.state.product.id,
        reference: this.state.product.reference,
        designation: this.state.product.designation        
        };

        axios
        .post(`/products/${this.props.match.params.id}`, data )
        .then(res => console.log(res))      
        .catch(err => console.log(err));
    };

这从产品中读取,但产品是一个数组。但是,这并不能反映在根handleChange中设置的内容。id, reference, designation这将导致 id、reference、designation 未定义,因为this.state.product它是一个数组。

可以做的一个可能的改变是handleChange

        const data = { 
        id: this.state.id,
        reference: this.state.reference,
        designation: this.state.designation        
        };

但这只有在用户更改了表单中的某些内容时才有效。我们还需要考虑用户可能只是点击提交的事实。

另外,我注意到另一个错误(可能不相关?-阅读评论):

  renderForm() {
        return this.state.product.map((product, index) => {
            const { id,reference,designation } = product // is this used?
        return(
            <>         
            <Form className="post" onSubmit={this.handleSubmit}>
                <Form.Row>
                    <Form.Group as={Col} controlId="formGridReference">
                    <Form.Label>Reference</Form.Label>
{/* this should be reference instead of this.state.product.reference? why is it set as placeholder? */}
                    <Form.Control type="text" value={this.state.product.reference} 
                        onChange={this.handleChange} name="reference" placeholder={reference} />
                    </Form.Group>

                    <Form.Group as={Col} controlId="formGridDesignation">
                    <Form.Label>Designation</Form.Label>
{/* this should be designation instead of this.state.product.designation? Why is designation set as a placeholder instead? */}
                    <Form.Control type="text" value={this.state.product.designation} 
                        onChange={this.handleChange} name="designation" placeholder={designation} />
                    </Form.Group>
                </Form.Row>                

                <Button variant="primary" type="submit">
                    Submit
                </Button>
            </Form>
            </>
            );
        })
    }

另外,如果目标是基于产品的单个产品提交更改,我会考虑创建一个ProductsList组件,它保持componentDidMount,然后创建一个Product具有handleChange和的组件handleSubmit


推荐阅读