When you enter react input, you will lose focus once, and you need to click again to enter it again.

if you have a question, you can enter it only once every time you click on input

.

looked at the code. The reason should be that every time I input and trigger onChange, the DOM is redrawn, but the root cause is not clear. Please give me some advice.

react
The

code is as follows:

class Goods extends Component {

    constructor() {
    super();
    this.state = {
        id: "",
        name: "",
        orderBy_id: 3,// 
        isFilter: false,
        type: "",//
        page_num: 1, // 
        min_price: "", // 
        max_price: "", // 
        screen_id: "", // 
        str: ""
    };
    this.changeSort = this.changeSort.bind(this);
    this.changeProd = this.changeProd.bind(this);
    this.selectedAttr = this.selectedAttr.bind(this);
    this.resetAttr = this.resetAttr.bind(this);
    this.selectedFilter = this.selectedFilter.bind(this);
    this.changePrice = this.changePrice.bind(this);
    this.closeModal = this.closeModal.bind(this);
}
changePrice(event) {
    const target = event.target;
    if(target.name === "min_price") {
        this.setState({
            min_price: event.target.value
        })
    }else {
        this.setState({
            max_price: event.target.value
        })
    }

}
 render() {
    const {data} = this.props;
    const SelectWrapper = () => {
        return (
            <TopWrapper>
                <TopItem className={(this.state.orderBy_id === 3 && !this.state.isFilter) ? "selected" : ""}
                         onClick={(e) => this.changeSort(e, "other", 3)}>
                    <span className="text"></span>
                </TopItem>
                <TopItem className={(this.state.orderBy_id === 5 && !this.state.isFilter) ? "selected" : ""}
                         onClick={(e) => this.changeSort(e, "other", 5)}>
                    <span className="text"></span>
                </TopItem>
                <TopItem
                    className={((this.state.orderBy_id === 2 || this.state.orderBy_id === 1) && !this.state.isFilter) ? "selected" : ""}
                    onClick={(e) => this.changeSort(e, "price")}>
                    <span className="text"></span>
                    <span className="icon">
                        <i className={`iconfont icon-shangjiantou ${this.state.orderBy_id === 2 ? "selected" : ""}`}></i>
                        <br/>
                        <i className={`iconfont icon-xiajiantou ${this.state.orderBy_id === 1 ? "selected" : ""}`}></i>
                    </span>
                </TopItem>
                <TopItem className={this.state.isFilter ? "selected" : ""}
                         onClick={(e) => this.changeSort(e, "shaixuan")}>
                    <span className="text"></span>
                    <span className="icon">
                        <i className="iconfont"></i>
                        <br/>
                        <i className={`iconfont icon-xiajiantou ${this.state.isFilter ? "selected" : ""}`}></i>
                    </span>
                </TopItem>
            </TopWrapper>
        )
    };
    const ProductContainers = () => {
        let isSelf = (type) => {
            if(type === "1") {
                return (
                    <span></span>
                )
            }
            return null;
        };
        if(!data.length){
            return null
        }
        return (
            <ProductWrapper>{
                data.map((item, index) => {
                    return (
                        <ProductItem key={index}>
                            <div className="img">
                                <img src={item.image} alt=""/>
                            </div>
                            <p className="name">
                                {
                                    isSelf(item.support_type)
                                }
                                {item.name}
                            

<p className="price"> <span> {(item.price).toFixed(2)} </span>

</ProductItem> ) }) } </ProductWrapper> ) }; const FilterContainer = () => { const {isFilter, screen_id, min_price, max_price} = this.state; const {options} = this.props; if(isFilter) { return ( <FilterWrapper> <div className="content"> <p className="title">

<ul> { options.map((item, index) => { if(screen_id.indexOf(item.id) > -1) { return ( <li key={index} onClick={() => {this.selectedAttr(item.id)}} className="screen-select">{item.name} <img className="selected" src="https://www.codeshelper.com/uploadfile/2022/0214/20220214120332625.png" alt=""/> </li> ) }else { return ( <li key={index} onClick={() => {this.selectedAttr(item.id)}}>{item.name}</li> ) } }) } </ul> <p className="title">

<p className="price-range"> <input type="text" name="min_price" placeholder="" onChange={this.changePrice} value={min_price} /> <span>-</span> <input type="text" name="max_price" placeholder="" onChange={this.changePrice} value={max_price}/>

<div className="buttons"> <p className="reset" onClick={this.resetAttr}>

<p className="sure" onClick={this.selectedFilter}>

</div> </div> <div className="model" onClick={this.closeModal}></div> </FilterWrapper> ) } return null }; return ( <Wrapper> <SelectWrapper/> <FilterContainer /> <ProductContainers/> </Wrapper> ) }

}

Feb.14,2022

is probably because the key value in the loop uses index .
because the diff algorithm in React needs to use the key value to determine whether the virtual dom has changed, and the value of index will change dynamically, it will lead to dom redrawing. Before
, I generated a dom structure containing input in the loop and used a timestamp as the key value.

< H2 > it is recommended to give key a fixed and unique value in any case. < / H2 >

I hope this will help you.


Don't have branch judgments in your render
return.

such as your if (isFilter). This is a bad practice, and it is easy to have all kinds of problems, including yours.


you now have three more subcomponents defined in render
take the components in render < SelectWrapper/ > < FilterContainer / > < ProductContainers/ >
, or write them as a method and put them in Goods


import React from 'react';
import {render} from 'react-dom';

const mountPoint = document.createElement('div');
mountPoint.setAttribute('id', 'root');
document.body.appendChild(mountPoint);


class Goods extends React.Component {
    constructor() {
        super();
        this.state = {
            id: '',
            name: '',
            orderBy_id: 3,// 
            isFilter: false,
            type: '',//
            page_num: 1, // 
            min_price: '', // 
            max_price: '', // 
            screen_id: '', // 
            str: ''
        };
        this.changePrice = this.changePrice.bind(this);
    }

    changePrice(event) {
        const target = event.target;
        console.log(event.target.value)
        if(target.name === 'min_price') {
            this.setState({
                min_price: event.target.value
            })
        }else {
            this.setState({
                max_price: event.target.value
            })
        }
    }

    filterContainer() {
        const {isFilter, screen_id, min_price, max_price} = this.state;
        return (
            <div>
                <div className='content'>
                    <p className='title'>

<p className='title'>

<p className='price-range'> <input type="text" name='min_price' placeholder='' onChange={this.changePrice} value={min_price} /> <span>-</span> <input type="text" name='max_price' placeholder='' onChange={this.changePrice} value={max_price}/>

</div> </div> ) }; render() { return ( <div> {this.filterContainer()}

min_price:{this.state.min_price}

max_price:{this.state.max_price}

</div> ) } } render( <Goods />, mountPoint );

has the landlord solved this problem? I also encountered


today because I used high-level components. The specific reason is not clear. It should be that when the state is changed, the render () method should be re-executed, and your input box is written in the high-level components, so it will lead to the re-execution of the method of your high-level components. To re-render your entire high-level components, it should be a bug of the react,diff algorithm!


this problem can be solved through uncontrolled input components

https://zh-hans.reactjs.org/d.

.
Menu