代码之家  ›  专栏  ›  技术社区  ›  Afsanefda

在fetch success函数中不更新React set state(在key up事件中)

  •  2
  • Afsanefda  · 技术社区  · 6 年前

    component 包含一个我定义了 key up event handler function

    class SearchBox extends Component {
        constructor(props) {
            super(props);
            this.state = {
                timeout: 0,
                query: "",
                response: "",
                error: ""
            }
            this.doneTypingSearch = this.doneTypingSearch.bind(this);
        }
        doneTypingSearch(evt){
            var query = evt.target.value; 
            if(this.state.timeout) clearTimeout(this.state.timeout);
            this.state.timeout = setTimeout(() => {
                fetch('https://jsonplaceholder.typicode.com/todos/1/?name=query' , {
                    method: "GET"
                })
                .then( response => response.json() )
                .then(function(json) {
                    console.log(json,"successss") 
                    //Object { userId: 1, id: 1, title: "delectus aut autem", completed: false }  successss
    
                    this.setState({
                        query: query,
                        response: json
                    })
                    console.log(this.state.query , "statesssAfter" )
                }.bind(this))
                .catch(function(error){
                    this.setState({
                        error: error
                    })
                });
            }, 1000);
        }
      render() {
        return (
            <div>
                <input type="text" onKeyUp={evt => this.doneTypingSearch(evt)} />        
                <InstantSearchResult data={this.state.response} /> 
            </div>
            );
        }
    }
    export default SearchBox;
    

    问题在于 setState .then() . 响应不会更新。我想更新它并将其传递给 InstantSearchResult 在这里导入的组件。你知道问题出在哪里吗?

    class InstantSearchBox extends Component {
        constructor(props) {
            super(props);
            this.state = {
                magicData: ""
            }
        }
        // Both methods tried but got error =>  Maximum update depth exceeded. This can happen when a component repeatedly calls setState inside componentWillUpdate or componentDidUpdate. React limits the number of nested updates to prevent infinite loops.
        componentDidUpdate(props) {
            this.setState({
                magicData: this.props.data
            })
        }
        shouldComponentUpdate(props) {
            this.setState({
                magicData: this.props.data
            })
        }
        render() {
            return (
                <h1>{ this.state.magicData}</h1>
            );
        }
    }
    export default InstantSearchBox;
    
    2 回复  |  直到 6 年前
        1
  •  5
  •   Afsanefda    6 年前

    编辑:

    setState asynchronous 阅读 this article

    我知道 在我的工作中很好 fetch success 问题在于 console.log 之后我就不该用了 设置状态 控制台.log 在里面 render() 我发现 state

    另一件我不小心的事是 InstantSearchResult Constructor re-render 这个 SearchBox 组成部分 InstantSearchResult constructor 只跑一次。如果我使用 InstantSearchResult实例 我将面临 infinite loop 所以我必须用 this.props 而是将数据传递给第二个组件。

        2
  •  2
  •   Kubwimana Adrien    6 年前

    this 已在promise回调函数中重写。要将其保存到变量,请执行以下操作:

    doneTypingSearch(evt){
            var _this = this,
                query = evt.target.value; 
            if(this.state.timeout) clearTimeout(this.state.timeout);
            this.state.timeout = setTimeout(() => {
                fetch('https://jsonplaceholder.typicode.com/todos/1/?name=query' , {
                    method: "GET"
                })
                .then( response => response.json() )
                .then(function(json) {
                    console.log(json,"successss") 
                    //Object { userId: 1, id: 1, title: "delectus aut autem", completed: false }  successss
    
                    _this.setState({
                        query: query,
                        response: json
                    })
                    console.log(_this.state.query , "statesssAfter" )
                }/*.bind(this)*/)
                .catch(function(error){
                    _this.setState({
                        error: error
                    })
                });
            }, 1000);
        }