簡體   English   中英

使用 d3 更新 dom ref 並做出反應

[英]update dom ref using d3 and react

我有一個帶有d3函數的functional component ,它在安裝時將p附加到ref

我正在嘗試使用useState掛鈎更改附加段落的文本內容

點擊按鈕<button type="button" onClick={(e)=> setData("bar")}>change data</button>觸發重新渲染,而不是更改p標簽的文本,一個新的d3 函數的版本被創建 --> 追加一個新的p

閱讀參考更改時如何重新渲染建議使用useCallback鈎子,我不確定如何實現

如何在不創建新段落的情況下實現段落的重新渲染?

import {useEffect, useState, useRef} from 'react'

import * as d3 from 'd3'

function DomReference() {

  const domRef = useRef()

  const [data, setData] = useState("foo")

  useEffect(()=>{


    d3.select(domRef.current)
      .append('p')
      .text(data)
    
    // re-render --> creates a new function 
    
  }, [data])


  return (
    <div ref={domRef}>
      <button type="button" onClick={(e)=> setData("bar")}>change data</button>
      
    </div>
  )
}

export default DomReference

d3 append 函數在執行時總是會創建一個新元素。

要始終只有一個段落並且只更新其值,您可以使用d3.join

代替:

  d3.select(domRef.current)
      .append('p')
      .text(data)

你可以使用:

  d3.select(domRef.current).selectAll('p')
    .data([data])
    .join('p')
    .text(d => d)

逐行解釋:

  • d3.select(domRef.current).selectAll('p') : 選擇domRef.current所有<p>元素
  • .data([data]) :將<p>元素綁定到數據數組。 綁定時,數組中的每個項目都有自己的<p>
  • .join('p')join將創建一個選擇,刪除所有沒有關聯數據的<p> ,並更新有數據的那些。 這將為您留下一個<p> ,因為之前的.data()調用在數組中只有一個元素
  • .text(d => d) :此回調是您訪問與<p>關聯的數據的方式。

作為補充:

如果您不想刪除所有其他<p> ,您可以使用一個類來縮小您的選擇范圍:

  d3.select(domRef.current).selectAll('p.myOddParagraphs')
    .data([1, 3, 5])
    .join('p')
    .classed('myOddParagraphs', true)
    .text(d => d)

   d3.select(domRef.current).selectAll('p.myEvenParagraphs')
    .data([2, 4, 6])
    .join('p')
    .classed('myEvenParagraphs', true)
    .text(d => d)

上面的代碼將導致 6 段:三個綁定到[1, 3, 5]數組,其他三個綁定到[2, 4, 6]

原則上,你不應該在使用 React 時嘗試使用 D3 來改變 DOM,因為 React 不會意識到這樣的變化。 這通常會導致很難發現和調試的非常討厭的錯誤。 如果你發現自己在 React 中使用了attrappend ,那你就錯了;)

這並不是說你不能在 React 中使用 D3。 正確的方法是始終將 DOM 操作留給 React,並使用 D3 作為計算屬性的引擎。 例如,當使用 d3 力布局時,您可以使用 D3 計算 (x,y) 坐標,並將它們作為道具傳遞,以便 React 處理協調等。

在上面的例子中,我建議將<p .../>的渲染留給 React。 但是,我不知道您的最終目標是什么,因此除了將這個示例簡單地轉換為 React 之外,無法真正說出正確的方法是什么

暫無
暫無

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

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