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

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

滾動到反應視圖中

滾動到反應視圖中

森欄 2023-08-24 10:02:47
我正在制作一個簡單的反應應用程序,其中有兩個不同的div's..具有選擇輸入和選定列表的一個,  <div id="container">    <div className="_2iA8p44d0WZ">      <span className="chip _7ahQImy">Item One</span>      <span className="chip _7ahQImy">Item Two</span>      <span className="chip _7ahQImy">Item Three</span>      <span className="chip _7ahQImy">Item Four</span>      <span className="chip _7ahQImy">Item Five</span>      <input        type="text"        className="searchBox"        id="search_input"        placeholder="Select"        autoComplete="off"        value=""      />    </div>  </div>另一個會將所選選項列出為fieldset,  <div>    {selectedElements.map((item, i) => (      <div key={i} className="selected-element" ref={scrollDiv}>        <fieldset>          <legend>{item}</legend>        </fieldset>      </div>    ))}  </div>基于這個解決方案,我已添加createRef到所選元素,例如,<div key={i} className="selected-element" ref={scrollDiv}></div>然后我采用 Javascript 查詢方法來獲取 DOM 元素,例如,  const chipsArray = document.querySelectorAll("#container > div > .chip");向所有元素添加了單擊事件偵聽器,例如,  chipsArray.forEach((elem, index) => {    elem.addEventListener("click", scrollSmoothHandler);  });然后scrollSmoothHandler就像,const scrollDiv = createRef();  const scrollSmoothHandler = () => {    console.log(scrollDiv.current);    if (scrollDiv.current) {      scrollDiv.current.scrollIntoView({ behavior: "smooth" });    }  };但這并沒有按預期工作。
查看完整描述

1 回答

?
弒天下

TA貢獻1818條經驗 獲得超8個贊

問題

  1. React.createRef實際上只在基于類的組件中有效。如果在功能組件主體中使用,則將在每個渲染周期重新創建引用。

  2. 不要使用 DOM 查詢選擇器將onClick偵聽器附加到 DOM 元素。這些存在于外部反應,您需要記住清理它們(即刪除它們),這樣就不會出現內存泄漏。使用 React 的onClickprop。

  3. 映射后,您將相同的selectedElements引用附加到每個元素,因此最后一組是您的 UI 獲取的元素。

解決方案

  1. 在功能組件主體中使用React.useRef來存儲反應引用數組,以附加到要滾動到視圖中的每個元素。

  2. scrollSmoothHandler將直接附加到每個spanonClick支柱上。

  3. 將 1. 中創建的引用數組中的每個引用附加到要滾動到的每個映射字段集。

代碼

import React, { createRef, useRef } from "react";

import { render } from "react-dom";


const App = () => {

  const selectedElements = [

    "Item One",

    "Item Two",

    "Item Three",

    "Item Four",

    "Item Five"

  ];


  // React ref to store array of refs

  const scrollRefs = useRef([]);


  // Populate scrollable refs, only create them once

  // if the selectedElements array length is expected to change there is a workaround

  scrollRefs.current = [...Array(selectedElements.length).keys()].map(

    (_, i) => scrollRefs.current[i] ?? createRef()

  );


  // Curried handler to take index and return click handler

  const scrollSmoothHandler = (index) => () => {

    scrollRefs.current[index].current.scrollIntoView({ behavior: "smooth" });

  };


  return (

    <div>

      <div id="container">

        <div className="_2iA8p44d0WZ">

          {selectedElements.map((el, i) => (

            <span

              className="chip _7ahQImy"

              onClick={scrollSmoothHandler(i)} // <-- pass index to curried handler

            >

              {el}

            </span>

          ))}

          <input

            type="text"

            className="searchBox"

            id="search_input"

            placeholder="Select"

            autoComplete="off"

            value=""

          />

        </div>

      </div>

      <div>

        {selectedElements.map((item, i) => (

          <div

            key={i}

            className="selected-element"

            ref={scrollRefs.current[i]} // <-- pass scroll ref @ index i

          >

            <fieldset>

              <legend>{item}</legend>

            </fieldset>

          </div>

        ))}

      </div>

    </div>

  );

};

解決方案#2

由于您無法更新divwith中的任何元素id="container",并且所有onClick處理程序都需要通過查詢 DOM 來附加,因此您仍然可以使用柯里化scrollSmoothHandler回調并將索引包含在范圍內。您需要一個鉤子來在初始渲染useEffect查詢 DOM ,以便安裝跨度,并需要一個鉤子來存儲“已加載”狀態。該狀態是觸發重新渲染并重新包含在回調中所必需的。useStatescrollRefsscrollSmoothHandler

const App = () => {

  const selectedElements = [

    "Item One",

    "Item Two",

    "Item Three",

    "Item Four",

    "Item Five"

  ];


  const [loaded, setLoaded] = useState(false);

  const scrollRefs = useRef([]);


  const scrollSmoothHandler = (index) => () => {

    scrollRefs.current[index].current.scrollIntoView({ behavior: "smooth" });

  };


  useEffect(() => {

    const chipsArray = document.querySelectorAll("#container > div > .chip");


    if (!loaded) {

      scrollRefs.current = [...Array(chipsArray.length).keys()].map(

        (_, i) => scrollRefs.current[i] ?? createRef()

      );


      chipsArray.forEach((elem, index) => {

        elem.addEventListener("click", scrollSmoothHandler(index));

      });

      setLoaded(true);

    }

  }, [loaded]);


  return (

    <div>

      <div id="container">

        <div className="_2iA8p44d0WZ">

          <span className="chip _7ahQImy">Item One</span>

          <span className="chip _7ahQImy">Item Two</span>

          <span className="chip _7ahQImy">Item Three</span>

          <span className="chip _7ahQImy">Item Four</span>

          <span className="chip _7ahQImy">Item Five</span>

          <input

            type="text"

            className="searchBox"

            id="search_input"

            placeholder="Select"

            autoComplete="off"

            value=""

          />

        </div>

      </div>

      <div>

        {selectedElements.map((item, i) => (

          <div key={i} className="selected-element" ref={scrollRefs.current[i]}>

            <fieldset>

              <legend>{item}</legend>

            </fieldset>

          </div>

        ))}

      </div>

    </div>

  );

};


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

添加回答

舉報

0/150
提交
取消
微信客服

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

幫助反饋 APP下載

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

公眾號

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