React Hooks useState 在一个 mouseOver 函数中更改多个元素状态只想更改鼠标悬停在一个上

React Hooks useState changing multiple elements state in one mouseOver function only want to change the moused over one

我在第 61-67 行有 followig componenet 控制 editIcon 的某些状态,它可以工作,但它会更改列中所有项目的列上方跨度的状态值,我希望它仅更改其所在的列项或行项以更改状态,即;将鼠标悬停在 span 元素上会显示一个编辑图标,其他多个 span 中不会显示。

这与状态在两个地方发生变化的面部有关,但我不知道如何将组件隔离为仅悬停的组件,而不是生成的其他组件。希望这是有道理的。

提前致谢

这是我的代码

import Link from "next/link";
import Layout from "../components/Layout";
import useSWR from "swr";
import { INPUT_VALUES } from "./formBuilder";
import { useQuery } from "@apollo/client";
import React, { useEffect, useState } from "react";
import styled from "styled-components";
import { RiEdit2Fill } from "react-icons/ri";
import { useRouter } from "next/router";

const Wrap = styled.div``;

const Grid = styled.div`
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(200px, 225px));
  background: lightgrey;
  /* grid-template-columns: 1fr 1fr 1fr 1fr; */
`;

const RowItem = styled.p`
  &:hover {
    cursor: pointer;
    background: lightyellow;
  }
`;

const fetcher = (url) => fetch(url).then((r) => r.json());

const HoverableRow = ({ rowEdit, d, i }) => {
  const [editState, setEditState] = useState(false);

  return (
    <RowItem
      onClick={() => rowEdit(d.ref["@ref"].id)}
      onMouseEnter={setEditState(true)}
      onMouseLeave={setEditState(false)}
      className="test"
    >
      <span>
        {Object.values(d.data)[i] ? Object.values(d.data)[i] : "null"}
      </span>
      <span>
        {editState ? (
          <a>
            <RiEdit2Fill />
          </a>
        ) : (
          <a></a>
        )}
      </span>
    </RowItem>
  );
};

const Value = ({ data, i }) => {
  const router = useRouter();

  const rowEdit = (id) => {
    console.log(id);
    router.push(`rowEdit/${id}`);
  };

  return (
    <div>
      {data ? (
        data.map((d) => (
          <div key={`${Object.values(d.data)[i]}-${i}`}>
            <HoverableRow {...{ rowEdit, d, i }} />
            {/* <p>{d.ref["@ref"].id}</p> */}
          </div>
        ))
      ) : (
        <>
          <p>loading</p>
        </>
      )}
    </div>
  );
};

const Home = () => {
  const { data, error } = useSWR("/api/data", fetcher);

  const { loading, error: inputError, data: inputNames } = useQuery(
    INPUT_VALUES
  );

  const [inputDataState, setInputDataState] = useState([]);

  useEffect(() => {
    const inputData = inputNames?.allFormInputVals?.data;
    setInputDataState(inputData);
  }, [inputNames]);

  //console.log(inputDataState);
  //console.log(data);

  data?.map((d, i) => {
    console.log(d);
  });

  return (
    <Layout>
      <h1>Welcome to your Catalog</h1>
      <Grid>
        {inputDataState?.map((item, i) => {
          return (
            <Wrap key={item._id}>
              <div>
                <h2>{item.name}</h2>
              </div>
              <form>
                <Value i={i} data={data} />
              </form>
            </Wrap>
          );
        })}
      </Grid>
    </Layout>
  );
};

export default Home;


把每个RowItem放到不同的组件中,这样每个就可以有一个单独的editState:

const HoverableRow = ({ rowEdit, d, i }) => {
    const [editState, setEditState] = useState(false);
    return (
        <RowItem
            onClick={() => rowEdit(d.ref["@ref"].id)}
            onMouseEnter={() => setEditState(true)}
            onMouseLeave={() => setEditState(false)}
            className="test"
        >
            <span>
                {Object.values(d.data)[i] ? Object.values(d.data)[i] : "null"}
            </span>
            <span>
                {editState ? (
                    <a>
                        <RiEdit2Fill />
                    </a>
                ) : (
                        <a></a>
                    )}
            </span>
        </RowItem>
    );
};

并改变

<div key={`${Object.values(d.data)[i]}-${i}`}>
    <RowItem
        ...

<div key={`${Object.values(d.data)[i]}-${i}`}>
  <HoverableRow {...{ rowEdit, d, i }} />
</div>