2017-08-30 54 views
0

在應用程序的很多地方,我們打電話給/search api,你從結果中選擇id,然後結果將被丟棄,因爲結果是暫時使用的,這使我覺得不值得保存它們甚至派遣行動(除了設置isLoading標誌)。但這會迫使我解決反應組件的承諾,是否認爲是不好的做法或反模式?React Component中是否考慮了反模式解析承諾?

如:

componentDidMount() { 
    this.props.doSearch(criterias) 
     .then(res => this.setState({ results: res.results })) 
    } 

回答

0

是的,這是ReactJS已知的反模式,因爲你不能保證在承諾解決的成分仍然存在。你可以在技術上檢查使用this.isMounted,但這也被認爲是反模式。

問題是,ReactJS並不是真的被設計成一個全功能的應用程序框架 - 當你真的只是一個V時,你有點推MV MVC。爲了最有效,React應該與一些其他庫(Redux非常受歡迎)可以存儲應用程序數據,然後React可以爲您呈現。最好將React視爲一個將內部UI狀態變爲實際UI的庫。這對管理狀態並不好。

請參閱https://facebook.github.io/react/blog/2015/12/16/ismounted-antipattern.html

+0

是的, ,我知道反應是爲了視圖,這就是爲什麼我問這個問題。我的問題出現了,因爲我覺得,一旦用戶選擇了ID,我就可以將其存儲在商店中,我必須再次清空商店的這一部分,因爲這是暫時的,也許還有其他方法可以做到這一點。 – Kossel

0

是的,它是在反應的反模式。組件卸載後可能會執行this.setState({ results: res.results })

最好的方法是將狀態(搜索掛起/搜索解析)移出反應組件。您可以利用redux + redux-thunkmobxflux來幫助您。對於簡單的情況,你可以建立一個可取消的承諾。

const makeCancelable = (promise) => { 
    let hasCanceled_ = false; 

    const wrappedPromise = new Promise((resolve, reject) => { 
    promise.then(
     val => hasCanceled_ ? reject({isCanceled: true}) : resolve(val), 
     error => hasCanceled_ ? reject({isCanceled: true}) : reject(error) 
    ); 
    }); 

    return { 
    promise: wrappedPromise, 
    cancel() { 
     hasCanceled_ = true; 
    }, 
    }; 
}; 

class MyComponent extends Component { 
    componentDidMount() { 
    this.cancellableSearch = makeCancelable(this.props.doSearch()); 
    this.cancellableSearch.then((res) => { 
     this.setState({ results: res.results }); 
    }).catch((reason) => { 
     if (!isCanceled.isCanceled) { 
     console.error('some error occurs', reason); 
     } 
    }) 
    } 

    componentWillUnmount() { 
    this.cancellableSearch.cancel(); 
    } 

    // ... 
} 

撤銷的承諾的代碼是從這裏複製:https://facebook.github.io/react/blog/2015/12/16/ismounted-antipattern.html

+0

我確實在我們的項目中使用了REDX。現在對於我稱爲搜索API的每個地方,我都必須將結果保存在商店的不同部分,並感覺它是多餘的,因爲一旦選擇了該ID,就不再需要結果 – Kossel