簡體   English   中英

反應組件不更新

[英]React component doesn't update

當我更改存儲數據數組的數據文件時,顯示該數據的組件不會更改。 我試圖過濾原始數據並僅獲取選定的值,它運行良好,但即使在數據更改后顯示也沒有改變。

這是關鍵組件的代碼和屏幕截圖在此處輸入圖像描述

單項組件:

function Item() {
  let [data, setData] = useContext(DataContext);

  let Array = data.map((item) => {
    return (
      <div className="Item">
        <img src={item.url} />
        <h1>{item.name}</h1>
        <p>{item.desc}</p>
        <h2>{item.price}</h2>
        <Link to={`/product/${item.path}`}>
          <h3>See details</h3>
        </Link>
      </div>
    );
  });

  return <>{Array}</>;
}

數據組件:

export let DataContext = createContext();

export let DataProvider = (props) => {
  let [data, setData] = useState([
    {
      name: "Toshiba",
      desc: "Laptop copmuter",
      price: 299,
      url:
        "https://images.pexels.com/photos/3975677/pexels-photo-3975677.jpeg?auto=compress&cs=tinysrgb&dpr=2&h=650&w=940",
      path: "Toshiba",
      type: "laptop",
      details:
        "Some words just to fill this space Some words just to fill this space Some words just to fill this space Some words just to fill this space Some words just to fill this space Some words just to fill this space Some words just to fill this space Some words just to fill this space",
    },
    {
      name: "Lenovo",
      desc: "Laptop copmuter",
      price: 399,
      url:
        "https://images.pexels.com/photos/3975677/pexels-photo-3975677.jpeg?auto=compress&cs=tinysrgb&dpr=2&h=650&w=940",
      path: "Lenovo",
      type: "laptop",
      details:
        "Some words just to fill this space Some words just to fill this space Some words just to fill this space Some words just to fill this spaceSome words just to fill this space Some words just to fill this space Some words just to fill this space Some words just to fill this space",
    },
    {
      name: "Asus",
      desc: "Laptop copmuter",
      price: 199,
      url:
        "https://images.pexels.com/photos/3975677/pexels-photo-3975677.jpeg?auto=compress&cs=tinysrgb&dpr=2&h=650&w=940",
      path: "Asus",
      type: "laptop",
      details:
        "Some words just to fill this space Some words just to fill this space Some words just to fill this space Some words just to fill this space Some words just to fill this space Some words just to fill this space Some words just to fill this space Some words just to fill this space",
    },
    {
      name: "HP",
      desc: "Laptop copmuter",
      price: 299,
      type: "laptop",
      url:
        "https://images.pexels.com/photos/3975677/pexels-photo-3975677.jpeg?auto=compress&cs=tinysrgb&dpr=2&h=650&w=940",
      path: "HP",
      details:
        "Some words just to fill this space Some words just to fill this space Some words just to fill this space Some words just to fill this space Some words just to fill this space Some words just to fill this space  Some words just to fill this space Some words just to fill this space Some words just to fill this space Some words just to fill this space ",
    },
    {
      name: "Apple",
      desc: "Laptop copmuter",
      price: 299,
      type: "laptop",
      url:
        "https://images.pexels.com/photos/3975677/pexels-photo-3975677.jpeg?auto=compress&cs=tinysrgb&dpr=2&h=650&w=940",
      path: "Apple",
      details:
        "Some words just to fill this space Some words just to fill this space Some words just to fill this space Some words just to fill this spaceSome words just to fill this space Some words just to fill this space Some words just to fill this space Some words just to fill this space",
    },
    {
      name: "Apple",
      desc: "Android",
      price: 299,
      type: "mobile",
      url:
        "https://images.pexels.com/photos/3975677/pexels-photo-3975677.jpeg?auto=compress&cs=tinysrgb&dpr=2&h=650&w=940",
      path: "Apple",
      details:
        "Some words just to fill this space Some words just to fill this space Some words just to fill this space Some words just to fill this spaceSome words just to fill this space Some words just to fill this space Some words just to fill this space Some words just to fill this space",
    },
  ]);

  return (
    <DataContext.Provider value={[data, setData]}>
      {props.children}
    </DataContext.Provider>
  );
};

店鋪組件:

function Shop() {
  let [data, setData] = useContext(DataContext);
  function mobileClick(e) {
    setData((prev) =>
      prev.filter((item) => {
        if (item.type === e.target.id) {
          return true;
        }
      })
    );
    console.log(data);
  }
  return (
    <div className="shopContainer">
      <div className="filter">
        <h1>Filter</h1>
        <form>
          <div>
            <label for="mobile">Mobile </label>
            <input type="checkbox" id="mobile" onClick={mobileClick} />
          </div>
          <div>
            <label for="mobile">Laptop </label>
            <input type="checkbox" id="laptop" />
          </div>
          <div>
            <label for="mobile">PC </label>
            <input type="checkbox" id="PC" />
          </div>
          <div>
            <label for="mobile">Touchpad </label>
            <input type="checkbox" id="Touchpad" />
          </div>
        </form>
      </div>
      <div className="main">
        <DataProvider>
          <Item />
        </DataProvider>
      </div>
    </div>
  );
}

抱歉之前的錯誤答案,所以我編輯了這個。

您的問題是您在Provider之外訪問state

因為您需要先使用Provider包裝Shop組件,然后您必須訪問其中的state

function App(){
  return (
    <Provider>
      <Shop />
    </Provider>
  )
}


function Shop(){
  const [state, setState] = useContext(defaultState);
  return (
     // YOUR REST JSX HERE...
  )
}

刪除Item的附加DataProvider 您已經在包裝整個應用程序時提供了一個。 目前,您的Item沒有從那個接收更新的data ,而是它必須從它最近的DataProvider接收未更改的數據。

Shop應該是:-

function Shop() {
  let [data, setData] = useContext(DataContext);
  function mobileClick(e) {
    setData((prev) =>
      prev.filter((item) => {
        if (item.type === e.target.id) {
          return true;
        }
      })
    );
    console.log(data);
  }
  return (
    <div className="shopContainer">
      <div className="filter">
        <h1>Filter</h1>
        <form>
          <div>
            <label for="mobile">Mobile </label>
            <input type="checkbox" id="mobile" onClick={mobileClick} />
          </div>
          <div>
            <label for="mobile">Laptop </label>
            <input type="checkbox" id="laptop" />
          </div>
          <div>
            <label for="mobile">PC </label>
            <input type="checkbox" id="PC" />
          </div>
          <div>
            <label for="mobile">Touchpad </label>
            <input type="checkbox" id="Touchpad" />
          </div>
        </form>
      </div>
      <div className="main">
          <Item />
      </div>
    </div>
  );
}

這是一個查看它的代碼框(不要介意css)

編輯冗余數據提供者

注意:- :當前選擇mobile也會將您的 state 永久設置為過濾后的數組,這將不允許您在原始數組上成功應用任何進一步的過濾器。 出於過濾目的,您始終需要維護原始數組的副本。

暫無
暫無

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

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