2017-05-03 15 views
13

我是新的反應/ redux的相對性。因爲我想問一個(也許是哲學的)問題。在componentDidMount上發送一個動作(react/redux)

可以在反應組件的componentDidMount上發送操作(例如觸發api-call)嗎?

如果不是,爲什麼以及應該在哪裏發送操作?

如果是,那麼沒有進一步的問題? :)

+5

是的,這是派遣,對於組件初始化數據動作*首選*地方。 –

+1

這裏有一些進一步的閱讀:https://facebook.github.io/react/docs/react-component.html –

+0

我應該如何使用'componentDidMount'在由redux連接生成的容器組件上?是否應該在包裝的展示組件中完成,並讓它通過事件向上吹到容器中?或者可能不使用連接並將自己訂閱到商店? – Pablote

回答

5

是的,調度componentDidMount()上的行動是好的,甚至建議做的事情,因爲它不會減慢初始UI渲染。

由於該功能在組件初始渲染後運行,請記住,您可能需要在渲染組件的那一刻到從api調用接收數據的那一刻。

0

當使用路由時,另一種推薦的方式來分派一個動作將是路由方法「onEnter」。這是爲了使組件不依賴於動作(或API調用)。

我個人認爲這兩種方法(componentDidMount與onEnter)都可以。程序員應該選擇哪種解決方案最適合他的應用程序。

3

是的,你應該明確地使用componentDidMount鉤子。

一個典型的使用情況而定:

  • 組件出現在屏幕上,例如桌子
  • 向服務器發出請求被觸發獲取數據
  • 噴絲/加載器顯示爲覆蓋組件
  • 數據返回
  • 微調控制器被刪除,數據顯示在表中。

我知道它有點長,但我的工作我自己對這個類型的問題有一段時間,所以我想我會分享以下模式;)

當組件支架,然後找取數據動作被觸發。在應用程序狀態的「isFetching」值確定所說的紡絲器是否被示出或不(我想我使用的「先進裝載機」或一些這樣的庫)

export default class MyComponent extends React.Component { 

    componentDidMount() { 
    AppDispatcher.dispatch({ 
     type: ActionTypes.FETCH_DATA, 
    }); 
    } 

    render() { 
    let isFetching = this.props.my.application.path.isFetching; 
    return (
     <Loader show={isFetching} message={'loading'}> 
     <div> 
      My Component 
     </div> 
     </Loader> 
    ); 
    } 
} 

然後,在商店中的則fetch_data觸發的請求:

class AppStore extends ReduceStore { 

    //...... 

    reduce(state, action) { 

    let imState = Immutable.fromJS(state); 

    switch (action.type) { 

     //...... 

     case ActionTypes.FETCH_DATA: 
     doGetRequest('/url_to_service'); 
     break; 

     //...... 
    } 
    return imState.toJS(); 
    } 
} 

的要求會是這個樣子:

function doGetRequest(endpoint, params = {}) { 

    //request is some kind of AJAX library. In my case 'superagent' 
    request.get(endpoint) 
    .set('Accept','application/json') 
    .query(params) 
    .end(
     (err, res) => { 
     if (res && res.ok) { 
      receiveData(endpoint, "SUCCESS", res); 
     } else { 
      receiveData(endpoint, "FAIL"); 
    }}); 
} 

建成後,將派遣然後另一個動作。

function receiveData(endpoint, state, responseData) { 
    AppDispatcher.dispatch(
    { 
     type: ActionTypes.SERVER_RESPONSE, 
     endpoint: endpoint, 
     state: state, 
     payload: responseData 
    } 
); 
} 

再回到店裏,第二個動作被捕獲而isFetching標誌被設置爲false,那麼應用程序數據的處理。

reduce(state, action) { 

    let imState = Immutable.fromJS(state); 

    switch (action.type) { 

     //...... 


     case ActionTypes.SERVER_RESPONSE: { 

     imState = imState.setIn(['my','application','path', 'isFetching'], false) 

     if (action.state == "SUCCESS") { 
      //do something with the action.response data (via state update) 
     }else if (action.state == "FAIL") { 
      //maybe show an error message (via state update) 
     } 
     break; 
     } 
    } 
    return imState.toJS(); 
    } 
} 

....所以這個典型的使用情況下使用兩個「動作」,從componentDidMount方法正被觸發的第一動作,以及第二動作請求完成後觸發。

希望這種模式可以幫助:)