React 使用 map 遍历出的input框无法连续输入值的问题

#1

    import React from 'react';
import axios from 'axios';

class Home extends React.Component {
    constructor() {
        super();
        this.state = {
            category: [], //获取商品分类
            products: [], //获取商品
            addCategory: '', //添加商品分类
            name: "", //添加商品名称
            summary: '', //这是简介
            price: '', //商品价格
            poster: "", //商品链接
            categoryID: "", //商品ID
            commodityNum: "" //商品数量
        }
    }
    getCategory() {
        axios.get("http://api.duopingshidai.com/category").then((res) => this.setState({category: res.data.categories})).catch(err => console.log(err))
    }
    getProduct(limit) {
        axios.get(`http://api.duopingshidai.com/products?limit=${limit}`).then(res => {
            this.setState({products: res.data.products});
            console.log("商品总数是" + res.data.totalCount);
        })
    }
    componentWillMount() {
        this.getCategory();
        this.getProduct(10);
    }
    handleForm = (e) => {
        e.preventDefault();
        axios.post("http://api.duopingshidai.com/category", {name: this.state.addCategory}).then(res => {
            this.getCategory();
            alert(res.data.msg)
        });
    }
    handleInput = (e) => {
        this.setState({addCategory: e.target.value})
    }
    handleInput2 = (e) => {
        this.setState({name: e.target.value})
    }
    handleInput3 = (e) => {
        this.setState({summary: e.target.value})
    }
    handleInput4 = (e) => {
        this.setState({price: e.target.value})
    }
    handleInput5 = (e) => {
        this.setState({poster: e.target.value})
    }
    handleInput6 = (e) => {
        this.setState({categoryID: e.target.value})
    }
    handleInput7 = (e) =>{
      // let index = this.state.products.findIndex(item=>item._id===e.target.id);
      //     this.state.products[index].__v = e.target.value;
      //     this.setState({products:this.state.products});
      //   console.log( this.state.products[index].__v);
      this.setState({commodityNum:e.target.value})
    }
    handleDelete(id) {
        axios.delete(`http://api.duopingshidai.com/category?id=${id}`).then(res => {
            let index = this.state.category.findIndex(item => item._id === id);
            this.state.category.splice(index, 1);
            this.setState({data: this.state.category});
        })
    }
    handleShowId(id) {
        console.log(id);
    }
    handleCommodity = (e) => {
        e.preventDefault();
        let commodity = {
            name: this.state.name,
            summary: this.state.summary,
            price: this.state.price,
            poster: this.state.poster,
            category: this.state.categoryID
        };
        axios.post("http://api.duopingshidai.com/product/new", commodity).then((res) => console.log(res)).catch((err) => console.log(err))
    }
    handleDeleteItem(id) {
        axios.delete(`http://api.duopingshidai.com/product/delete/${id}`).then(res => {
            let index = this.state.products.findIndex(item => item._id === id);
            this.state.products.splice(index, 1);
            this.setState({data: this.state.products});
        })
    }
    handleAddItem(id, num) {
        let commodityNum = {
            product: id,
            num: num
        }
        axios.post("http://api.duopingshidai.com/shopping/add", commodityNum).then(res => alert(res.data.msg))
    }
    render() {
        return (
            <div className="commodity">
                <div className="category">
                    <span>商品分类:</span>
                    {this.state.category.map(item => <span key={Math.random()} className="categoryItem">
                        <a href="#" key={Math.random()}>
                            {item.name}
                        </a>
                        <button onClick={this.handleDelete.bind(this, item._id)}>删除</button>
                        <button onClick={this.handleShowId.bind(this, item._id)}>显示ID</button>
                    </span>)}
                </div>
                <span>商品列表:</span>
                <div className="commodityList">
                    {this.state.products.map(item => <div className="commodityListItem" key={Math.random()}>
                        <span>商品名称:</span>
                        <span>{item.name}</span><br/>
                        <span>商品描述:</span>
                        <span>{item.summary}</span><br/>
                        <span>商品价格:</span>
                        <span>{item.price}</span><br/>
                        <img src={item.poster}/><br/>
                        <span>商品ID:</span>
                        <span>{item._id}</span><br/>
                        <button onClick={() => this.setState({
                          commodityNum: this.state.commodityNum + 1
                        })}>+</button>
                        <input type="text"  value={this.state.commodityNum} onChange={this.handleInput7}/>
                        <button onClick={() => this.setState({
                          commodityNum: this.state.commodityNum > 0
                          ? this.state.commodityNum - 1
                          : 0
                        })}>-</button>
                        <button onClick={this.handleDeleteItem.bind(this, item._id)}>删除</button>
                        <button onClick={this.handleAddItem.bind(this, item._id)}>添加购物车</button>
                    </div>)
}
                </div>

                <form onSubmit={this.handleForm}>
                    <label>添加商品分类:</label>
                    <input type="text" onChange={this.handleInput}/>
                    <input type="submit"/>
                </form>
                <form onSubmit={this.handleCommodity}>
                    <div>添加商品:</div>
                    <label>商品名:</label>
                    <input type="text" onChange={this.handleInput2}/><br/>
                    <label>商品简介:</label>
                    <input type="text" onChange={this.handleInput3}/><br/>
                    <label>商品价格:</label>
                    <input type="text" onChange={this.handleInput4}/><br/>
                    <label>商品链接:</label>
                    <input type="text" onChange={this.handleInput5}/><br/>
                    <label>商品类ID:</label>
                    <input type="text" onChange={this.handleInput6}/><br/>
                    <input type="submit"/>
                </form>
            </div>
        )
    }
}
export default Home
#2

为什么不能连续输入,打一个字母就失去焦点了,需要再点击才能输,这个input 是放在map函数中遍历出来的节点,问题在这里。移出map函数就正常了,但是不知道怎么解决。第一次发帖,有不妥之处还请见谅。:grimacing:

#3

处理这个表单的是: handleInput7这个函数

#4

大概的想法是记住当前change的input,然后遍历之后componentDidUpdate里面获取元素,然后focus。
不知道可否有其他最佳实践

#5

谢谢大神的回复,我刚刚发现了问题的根源所在,把 key={Math.random()} 改成 key={index},就可以了,这破事整了我一天时间,吐血:sob: ,但是还是不知道为什么。

#6

说明你要重视key这个属性,render前后会根据这个key来识别是不是同一个,所以你用key={index}的时候,如果动态增加或减少了,也会出现错乱的问题

1 Like