簡體   English   中英

我如何強制 React 重新渲染頁面上來自 array.map 的所有組件?

[英]How can I force React to re-render all components on a page that come from array.map?

我有一個父組件(游戲),它從一個數組中渲染子組件(卡片)。 我還有一個 Menu 組件,它會回調 Game 以更改其 state。當我更改級別時(從菜單中單擊按鈕),我希望所有當前卡片淡出,然后淡入新卡片,因此它們模仿淡入淡出-in CSS 應用於新渲染的卡片。 我在幾個地方嘗試過 forceUpdate,並傳遞虛擬道具來檢查更改。 基本上,我希望頁面上當前的所有卡片都重新呈現,而頁面在需要時呈現新卡片。

這是游戲中的一個片段:

{this._gameArray.map( (item, i) => {
  let dummyProp = Math.random();
  return <Card key={i}
           ...
           dummyProp={dummyProp}/>
})}

以及 Card 中的一個片段:

componentWillReceiveProps(nextProps) {
  ...
  if (nextProps.dummyProp !== this.props.dummyProps) {
    this.forceUpdate();
  }
}

我將 componentWillReceiveProps 用於另一個目的,並決定嘗試使用它來測試 dummyProp 更改。 新卡片淡出,但之前的卡片不做任何事情。

React 有一些算法來定義應該重新渲染哪些組件,在您的情況下,React 不會重新渲染組件,因為您使用索引作為鍵和索引是相同的。 您需要在重新渲染之間更新key

作為最簡單的解決方案,您可以在密鑰中使用索引 + 一些線索,如下所示:

<Card key={index + '-' + Date.now()} card={card}/>;

在這種情況下,每次<Game/>組件的 state 更改時,都會重新渲染<Card/>組件。

 class Card extends React.Component { constructor(props) { super(props) } render() { return ( <div class="card">Card {this.props.card.name}</div> ) } } class Game extends React.Component { constructor(props) { super(props) this.state = { counter: 0, cards: [ { name: 'Card1' }, ] } } increaseCounter = () => { this.setState({ counter: this.state.counter + 1 }) } render() { return ( <div> <h2 onClick={this.increaseCounter}>Click me: {this.state.counter}</h2> <h3>Will be re-rendered</h3> {this.state.cards.map((card, index) => { return <Card key={index + '-' + Date.now()} card={card} />; })} <h3>Won't be re-rendered</h3> {this.state.cards.map((card, index) => { return <Card key={index} card={card} />; })} </div> ) } } ReactDOM.render(<Game />, document.querySelector("#app"))
 body { background: #20262E; padding: 20px; font-family: Helvetica; } #app { background: #fff; border-radius: 4px; padding: 20px; transition: all 0.2s; } h2 { font-weight: bold; margin-bottom: 15px; }.card{ animation: fade-in-out 3000ms ease-in-out forwards; } @keyframes fade-in-out { 0% { background-color: transparent; } 50% { background-color: red; } 100%{ background-color: transparent; } }
 <script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script> <div id="app"></div>

但是,對於實際應用程序,我建議您考慮使用一些 React animation 庫,例如react-transition-group ,因為如果您僅使用 CSS 制作卡片動畫,如果重新渲染速度更快,可能會有一些閃爍比 animation 超時。

您可以簡單地嘗試不同的技巧。 如果您希望所有組件在每次級別更改時重新渲染,您可以使用 boolean,在開始更改時將其設置為 false,並在完成更改/一段時間后將其設置為 true。 然后給元素的渲染加上條件。

{shouldRender && this._gameArray.map( (item, i) => {
  let dummyProp = Math.random();
  return <Card key={i}
           ...
           dummyProp={dummyProp}/>
})}

當 shouldRender 為 true 時,卡片將被渲染,而當它為 false 時,則不會。 這樣每次都是真的,它們都會重新渲染,你就會有效果。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM