![](/img/trans.png)
[英]React.js Can I use array.map within componentDidMount() on an array returned from an axios request?
[英]In React.js should I make my initial network request in componentWillMount or componentDidMount?
在 react 文檔中,它建議在componentDidMount
方法中進行初始網絡請求:
componentDidMount()
在組件安裝后立即調用。 需要 DOM 節點的初始化應該在這里進行。 如果您需要從遠程端點加載數據,這是實例化網絡請求的好地方。 在此方法中設置狀態將觸發重新渲染。
如果componentWillMount
被渲染組件之前調用,是不是更好,使請求,並在這里設置的狀態? 如果我在componentDidMount
這樣做,則呈現組件,發出請求,更改狀態,然后重新呈現組件。 為什么在呈現任何內容之前提出請求不是更好?
您應該在componentDidMount
執行請求。
如果在渲染組件之前調用componentWillMount,那么在這里發出請求並設置狀態不是更好嗎?
不,因為無論如何,在組件呈現時請求都不會完成。
如果我在componentDidMount中執行此操作,則會呈現組件,發出請求,更改狀態,然后重新呈現組件。 為什么在呈現任何內容之前提出請求更好?
因為任何網絡請求都是異步的 。 除非你緩存了數據,否則無論如何都無法避免第二次渲染(在這種情況下,您根本不需要觸發請求)。 通過先前觸發它,你無法避免第二次渲染。 它無濟於事。
在React的未來版本中,我們希望componentWillMount
在某些情況下會多次觸發,因此您應該將componentDidMount
用於網絡請求 。
您應該使用componentDidMount
。
為什么在呈現任何內容之前提出請求更好?
因為:
componentWillMount
(如果適用) 但是,如果您要問,在componentWillMount
啟動請求是不是更好(沒有實際處理它),我肯定會說是(ES6),我自己這樣做偶爾會從加載中減少幾毫秒時間:
componentWillMount() {
// if window && window.XMLHttpRequest
if (!this.requestPromise) {
this.requestPromise = new Promise(resolve => {
// ... perform request here, then call resolve() when done.
});
}
}
componentDidMount() {
this.requestPromise.then(data => ...);
}
這將在componentWillMount
期間開始預加載您的請求,但請求僅在componentDidMount
處理,無論是當時已完成還是仍在進行中。
您應該在componentDidMount中發出請求,因為不應在componentWillMount中進行副作用請求。 可以在componentWillMount中設置setState,如果在componentDidMount中設置了state,則會立即觸發第二次重新渲染。
你會讀到它是一個反模式(UGHHH)並且一些短信禁止它(eslint-react-plugin),但是我不會非常注意它,因為有時它是與DOM交互的唯一方式。 您可以在willMount中設置默認狀態,也可以在方法屬性(state = {})中設置默認狀態,如果您正在使用關聯的babel階段
正如您所說,組件將只渲染一次,但這很好,因為您可以顯示某種Loader或資源正在加載的任何其他形式的信息。
class MyComp extends Component {
// What I do with stage 0
state = { mystate: 1 }
// What you might want to do if you're not
// on the experimental stage, no need to do
// the whole constructor boilerplate
componentWillMount() {
this.setState({ mystate: 1 });
}
componentDidMount() {
dispatch(yourAction());
// It's fine to setState here if you need to access
// the rendered DOM, or alternatively you can use the ref
// functions
}
render() {
if (!this.props.myCollection) return <Loader />
return (
<div> // your data are loaded </div>
)
}
}
在 render 方法之前避免在生命周期鈎子中獲取的真正原因是因為 React 社區計划使 render 方法調用異步。
在此處查看 gaeron 的回復: https : //github.com/reactjs/reactjs.org/issues/302
現在這意味着在渲染之前在任何生命周期方法中放置一個異步操作,如 fetch(或任何與此相關的異步操作),將干擾渲染過程。
所以不像你今天想象的同步執行:
1. 構造函數<< 想象在這里觸發 fetch() >> => 2. getDerivedStateFromProps << fetch 完成,回調通過事件循環添加到回調隊列 >> => 3. render => 4. componentDidMount => 5. 回調執行添加它們的順序,以便獲取回調現在運行。
它會是這樣的:
1. 構造函數<< 想象在這里觸發 fetch() >> => 2. getDerivedStateFromProps << 同時,獲取完成並且回調被排隊 >> << 想象在這里觸發異步 render() 。 它的回調也被排隊 >> => 回調按照它們添加的順序執行3. 所以 fetch 回調首先運行=> 4. 渲染回調運行=> 5. componentDidMount
這種干擾可能會導致狀態更改被還原,因為渲染可能會應用一個較早的狀態來覆蓋由 fetch 所做的更改。
另一個原因是,componentDidMount 生命周期保證了相應組件在 DOM 上的存在,如果 fetch 嘗試在 DOM 可用或更新之前對其進行操作,則可能導致應用程序顯示錯誤。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.