【问题标题】:React JS reduce API calls in functionReact JS 减少函数中的 API 调用
【发布时间】:2021-09-26 23:46:18
【问题描述】:

如您所见,我调用了我的 API 3 次。一次在 componentDidMount 中,两次在每个函数中。如何在 componentDidMount() 中将 API 调用次数减少到一次,以提高代码效率?

这是从生成列表的 API 进行的简单调用,我正在执行与列表一起使用的类别下拉列表搜索字段

我认为需要将函数中的某些内容移到其他地方才能正常工作。有什么想法吗?

constructor(props){
        super(props);
        this.state = {
            items: [],
            isLoaded: false,
        }

        this.ChangeCategory = this.ChangeCategory.bind(this);
        this.btnSearch = this.btnSearch.bind(this);
    }

componentDidMount(){
        fetch('https://examplejson.json')
            //use es6 arrow function to not lose context of 'this'
            .then(res => res.json())
            .then(json => {
                this.setState({
                    isLoaded: true,
                    items: json.response,
                })

                var items = json.response;

                //Populate category into dropdownlist
                var select = document.getElementById("locality");
                var options = [];
                var option = document.createElement('option');
                var i = 0;

                var uniqueNames = [];
                for(i = 0; i< items.length; i++){
                    if(uniqueNames.indexOf(items[i].category) === -1){
                        uniqueNames.push(items[i].category);        
                    }        
                }

                for(i = 0; i< uniqueNames.length; i++){    
                    option.text = option.value = option.key = uniqueNames[i];
                    options.push(option.outerHTML);      
                }

                select.insertAdjacentHTML('beforeEnd', options.join('\n'));
                //Populate category into dropdownlist
            }).catch(console.log);
            
    }

我的两个功能

ChangeCategory(){
        fetch('https://examplejson.json')
        .then(res => res.json())
        .then(json => {
            var category;
            var x;
  
            category = json.response;
    
            var result = category.filter((z)=>z.category === document.getElementById("locality").value);

            var items2 = [];
            for (x in result) {
                items2[x] = result[x];
            }

            this.setState({
                items: items2,
            })
            
        }).catch(console.log);

        document.getElementById("txtBox1").value = '';

    }

btnSearch(){    
        fetch('https://examplejson.json')
        .then(res => res.json())
        .then(json => {
            var items;
            var y;
            var searchItem = [];

            items = json.response;
    
            //filter by channel name, search the list with keyword from textbox (don't need to be exact word)
            var result = items.filter((z)=>z.title.toUpperCase().indexOf(document.getElementById("txtBox1").value.toUpperCase()) !== -1);
            
            for (y in result) {
                searchItem[y] = result[y];
            }
    
            this.setState({
                items: searchItem,
            })
            
        }).catch(console.log);
    
        document.getElementById("locality").selectedIndex = 0;
    }

渲染

render() { 

        var { isLoaded, items } = this.state;

        if(!isLoaded) {
            return <div>Loading...</div>;
        }

        else {
            return (

                
            <div className="list">
                <div className="row mb-5">

                    <div className="col-md-6 col-sm-12 category-wrap">
                        <select key="locality" id="locality" className="form-control" name="locality" onChange={this.ChangeCategory} style={{padding:"5px", width:"250px"}}>
                            <option>Select category</option>
                        </select>
                    </div>

                    <div className="col-md-6 col-sm-12 search-wrap">
                        <div className="input-group" style={{width:"250px"}}>
                            <input key="txtBox1" type="text" id="txtBox1" className="form-control" placeholder="Channel Name" onKeyPress={event => {
                                if (event.key === 'Enter') {
                                this.btnSearch()
                                }
                            }}/>
                            <button id="btnClick1" className="btn" onClick={this.btnSearch}><i className="bi bi-search"></i></button>
                        </div>
                    </div>
                </div>
                ...

【问题讨论】:

    标签: json reactjs api


    【解决方案1】:
    componentDidMount(){
        fetch('https://examplejson.json')
            .then(res => res.json())
            .then(json => {
                // There could be some logic to modify items, like uniqueness
                this.setState({
                    isLoaded: true,
                    items: json.response, // Items used for filtering
                    filteredItems: json.response, // Items to render
                })
            )}
    }
    

    然后,在函数 btnSearch 和 ChangeCategory 中,您可以使用“this.state.items”而不是调用 api 并使用响应。

    我也不推荐使用 document.getElementById(或 document.createElement ...)。而是使用状态。

    <input
        value={this.state.text}
        onChange={(e) => setState({ text: e.target.value })}
    />
    

    这样的渲染选项:

    <select name="locality" onChange={this.ChangeCategory} value={this.state.value}>
        {this.state.options.map((item) => {
            return <option key={item} value="select">{item}</option>
        })}
    </select>
    

    如果您仍需要访问 DOM 元素,请考虑使用“refs”。

    编辑:

    https://codesandbox.io/s/testapp-nekot 我就是这个意思

    • 了解受控组件与不受控组件的含义
    • 如何呈现集合
    • 除非您在应用程序中需要一些魔法,否则您不应该使用 document.getElementById

    【讨论】:

    • 感谢您的回复。但是这里有一些问题。对于选择输入字段,它给了我一个错误TypeError: Cannot read property 'map' of undefined。错误指向我的style={{padding:"5px", width:"250px"}}&gt;,我在它后面粘贴了value={this.state.value}。对于文本输入字段,我对如何将document.getElementById 合并或替换为您建议的状态感到困惑。
    • @HaydenNg 那是不完整的代码,我以为你会完成它。使用代码框查看编辑后的答案。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-01-26
    • 2022-01-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多