亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

為 React Bootstrap ListGroup 實現類型的問題

為 React Bootstrap ListGroup 實現類型的問題

HUX布斯 2023-05-11 16:44:08
我正在這個 React App 中實現 typescript。我正在使用 react-bootstrap(已經安裝了類型)。我有一個列表組,其中包含如下操作項。要獲取我擁有的每個項目的點擊事件的類型:((event: React.MouseEvent<HTMLAnchorElement, MouseEvent>) => void) 不確定為什么它會建議這種類型,因為當我檢查 DOM 時,我看到了按鈕。不管怎樣,下面是列表組的代碼。<ListGroup id="riskQuestion-1" >   <ListGroup.Item action onClick={(event:((event: React.MouseEvent<HTMLAnchorElement, MouseEvent>) => void) | undefined) => handleInput(setRiskAnswer1, 5, event)} >I was great!</ListGroup.Item>   <ListGroup.Item action onClick={(event:((event: React.MouseEvent<HTMLAnchorElement, MouseEvent>) => void) | undefined) => handleInput(setRiskAnswer2, 3, event)}>I did good but can be better</ListGroup.Item></ListGroup>    那么我的 handleInput 函數是: const [riskAnswer1, setRiskAnswer1] = useState<number | null>(null); const [riskAnswer2, setRiskAnswer2] = useState<number | null>(null); interface InputParams {    answerHandler:React.Dispatch<React.SetStateAction<number | null>>,    value: number,    event: ((event: React.MouseEvent<HTMLAnchorElement, MouseEvent>) => void) | undefined  }  function handleInput({answerHandler, value, event}:InputParams) {    event.preventDefault();    const parentEl = event.target.parentNode;    const  parentId = parentEl.getAttribute("id");    if (parentId) {      const el = document.getElementById(parentId);      if (el) {        for (let i=0; i < el.children.length; i++) {          if (el.children[i].classList.contains('selected')) {            el.children[i].classList.remove('selected');          }        }      }    }        event.target.classList.add("selected");    answerHandler(value);  }我在這段代碼中確實有一些 event.target 問題,但這可能與手頭的主要問題有關,也可能無關。現在的主要問題是打字稿仍然顯示錯誤onClick。當我將鼠標懸停在下方時,就是我所看到的。所以兩個問題:1-我需要改變什么2- 起初我將所有類型的參數內聯在括號內,但我將它們移到interface InputParams現在有了這個更改,我在列表組項目上調用 handleInput,我看到了這個錯誤:Expected 1 arguments, but got 3.ts(2554)所以似乎 function handleInput({answerHandler, value, event}:InputParams) {不是正確的方法在這里實現類型?不要擔心上面的所有錯誤都是在我將所有參數類型都內聯時生成的。所以這只是我想問的額外問題。感謝任何指導。謝謝你!
查看完整描述

1 回答

?
蠱毒傳說

TA貢獻1895條經驗 獲得超3個贊

問題是onClick處理程序的當前類型簽名基本上聲明參數event本身是一個函數。要糾正這個問題,您只想使用事件本身的類型:


<ListGroup id="riskQuestion-1">

  <ListGroup.Item

    action

    onClick={(event: React.MouseEvent<HTMLAnchorElement, MouseEvent>) =>

      handleInput(setRiskAnswer1, 5, event)

    }

  >

    I was great!

  </ListGroup.Item>

  <ListGroup.Item

    action

    onClick={(event: React.MouseEvent<HTMLAnchorElement, MouseEvent>) =>

      handleInput(setRiskAnswer2, 3, event)

    }

  >

    I did good but can be better

  </ListGroup.Item>

</ListGroup>

事實上,由于您不想訪問僅在元素上找到的屬性<a>,您可以讓類型默認為最廣泛的類型:Element,這樣您就可以省略泛型。它在這里的原因HTMLAnchorElement是ListGroup.Item帶有一個action呈現鏈接 - 使用瀏覽器的開發人員工具的 DOM 檢查器查看生成的 HTML。你會看到<a>那里。雖然它可以是任何東西,實際上你可以通過asprop指定它。


<ListGroup id="riskQuestion-1">

  <ListGroup.Item

    action

    onClick={(event: React.MouseEvent) =>

      handleInput(setRiskAnswer1, 5, event)

    }

  >

    I was great!

  </ListGroup.Item>

  <ListGroup.Item

    action

    onClick={(event: React.MouseEvent) =>

      handleInput(setRiskAnswer2, 3, event)

    }

  >

    I did good but can be better

  </ListGroup.Item>

</ListGroup>

要解決你的第二個問題,function handleInput({answerHandler, value, event}:InputParams)是一個接受一個參數的函數,該參數是具有這些屬性的對象。但是,您handleInput使用三個單獨的參數進行調用,因此它應該是:


function handleInput(

  answerHandler: React.Dispatch<React.SetStateAction<number | null>>,

  value: number,

  event: React.MouseEvent

)

由于您不在此處使用功能更新,因此您可以擺脫以下問題:


function handleInput(

  answerHandler: (answer: number | null) => void,

  value: number,

  event: React.MouseEvent

)

解決這些問題后,更多問題出現在handleInput. 第一個是 thatevent.target可能不是一個元素,因此它的類型沒有.parentNode. 在這種情況下,最好使用.currentTarget. 另請參閱javascript 中的 currentTarget 屬性和 target 屬性之間的確切區別是什么。


修改后的函數為:


function handleInput(

  answerHandler: (answer: number | null) => void,

  value: number,

  event: React.MouseEvent

) {

  event.preventDefault();


  const parentEl = event.currentTarget.parentNode;

  const parentId = parentEl.getAttribute("id");

  if (parentId) {

    const el = document.getElementById(parentId);

    if (el) {

      for (let i = 0; i < el.children.length; i++) {

        if (el.children[i].classList.contains("selected")) {

          el.children[i].classList.remove("selected");

        }

      }

    }

  }


  event.currentTarget.classList.add("selected");

  answerHandler(value);

}

但是,唉,又出現了一個錯誤。這次是因為parentNode是類型Node。實際上有很多節點類型,“元素”只是其中之一!但顯然,您實際上對父元素感興趣,因此通過更改parentNode為parentElement,函數編譯:


function handleInput(

  answerHandler: (answer: number | null) => void,

  value: number,

  event: React.MouseEvent

) {

  event.preventDefault();


  const parentEl = event.currentTarget.parentElement;

  const parentId = parentEl.getAttribute("id");

  if (parentId) {

    const el = document.getElementById(parentId);

    if (el) {

      for (let i = 0; i < el.children.length; i++) {

        if (el.children[i].classList.contains("selected")) {

          el.children[i].classList.remove("selected");

        }

      }

    }

  }


  event.currentTarget.classList.add("selected");

  answerHandler(value);

}

作為結束語,我只是一般性地說,這種直接的 DOM 操作在 React 世界中非常粗略,并且在大多數情況下可以而且應該用 React 來實現。


查看完整回答
反對 回復 2023-05-11
  • 1 回答
  • 0 關注
  • 223 瀏覽
慕課專欄
更多

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號