簡體   English   中英

我應該如何在 React 功能組件的列表中更新單個項目的 className onClick?

[英]How should I update individual items' className onClick in a list in a React functional component?

我是 React 的新手,我一直試圖讓這個 onClick function 正常工作。

我有一個組件“行”,其中包含一個動態的 div 列表,它從 function 獲取並返回它們:

export function Row({parentState, setParentState}) {
    let divList = getDivList(parentState, setParentState);
    
    return (
        <div>
            {divList}
        </div>
    )
}

說 parentState 可能只是:

[["Name", "info"],
["Name2", "info2"]]

function 返回一個 div 列表,每個 div 都有自己的 className 根據parentState中的數據確定。 每個人都需要能夠使用 onClick function 在parentState中更新自己的信息,而這又必須更新 className 以便 div 的外觀可以更改。 到目前為止,我的代碼似乎正確更新了 parentState (React Devtools 顯示了更改,至少當我出於某種原因離開組件然后導航回來時),但不會更新 className 直到以后的事件。 現在它看起來像這樣:

export function getDivList(parentState, setParentState) {
//parentState is an array of two-element arrays

    const divList = parentState.map((ele, i) => {
        let divClass = "class" + ele[1];

        return (
            <div
                key={ele, i}
                className={divClass}
                onClick={() => {
                    let newParentState = 
                        JSON.parse(JSON.stringify(parentState);
                    newParentState[i][1] = "newInfo";

                    setParentState(newParentState);}}>
                {ele[0]}
            </div>
        )
    }
    return divList;
}

我曾嘗試使用 useEffect,可能是錯誤的,但沒有運氣。 我該怎么做?

由於您的Row組件將parentState作為道具,我假設它是包含parentState的此父組件的直接子組件。 您正在嘗試訪問Row組件中的getDivList而不將其作為道具傳遞,如果您以這種方式編寫代碼,它將無法工作。

你可以使用 React 提供的children屬性,它允許你編寫一個帶有開始和結束標簽的組件: <Component>...</Component> 里面的一切都會在children 對於您的代碼,它看起來像這樣:

import React from 'react';
import { render } from 'react-dom';
import './style.css';

const App = () => {
  const [parentState, setParentState] = React.useState([
    ['I am a div', 'bg-red'],
    ['I am another div', 'bg-red'],
  ]);

  React.useEffect(
    () => console.log('render on ParentState changes'),
    [parentState]
  );

  const getDivList = () => {
    return parentState.map((ele, i) => {
      return (
        <div
          key={(ele, i)}
          className={ele[1]}
          onClick={() => {
            // Copy of your state with the spread operator (...)
            let newParentState = [...parentState];

            // We don't know the new value here, I just invented it for the example
            newParentState[i][1] = [newParentState[i][1], 'bg-blue'];

            setParentState(newParentState);
          }}
        >
          {ele[0]}
        </div>
      );
    });
  };

  return <Row>{getDivList()}</Row>;
};

const Row = ({ children }) => {
  return <>{children}</>;
};

render(<App />, document.getElementById('root'));

還有一點 css 的例子:

.bg-red {
  background-color: darkred;
  color: white;
}

.bg-blue {
  background-color:aliceblue;
}

這是StackBlitz 的復制品,因此您可以使用它。

我假設了parentState的形狀,yu 必須根據您的需要進行調整,但應該是這樣的。

現在,如果您的數據需要在多個組件之間共享,我強烈建議您使用上下文。 這是我對另一篇文章的回答,您將在其中找到有關如何實現上下文 Api 的簡單示例。

暫無
暫無

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

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