来自array的redux子组件

发布于 2025-02-12 13:11:07 字数 5959 浏览 1 评论 0原文

因此,这是组件的流量:

在主组件中,我从Redux Store中获得了使用UseElector Hook的状态。

const state = useSelector((state) => state);

我正在渲染我的按钮组件并将其传递给导致重新渲染的状态:

<TalentButton
              imgSrc={Ferocity}
              talentName="FerocityToolTip"
              req="15"
              spec="1"
              maxPoints="5"
              playableClass="Hunter"
              state={state}
              parentTalent={["1"]}
              arrows={[
                {
                  arrowType: "downMedium",
                  color: "silver",
                  parentTalent: "1",
                  spec: "1",
                },
              ]}
              id="11"
            />

在TalentButton组件内部,它返回地图功能中的一系列箭头组件。问题在于,即使在react devtools中可见正确的状态,也不会重新渲染此。映射中的组件。

{props?.arrows?.map((item) => {
        return (
          <Arrow
            arrowType={item.arrowType}
            parentTalent={item.parentTalent}
            childTalent={
              item?.childTalent !== undefined ? item?.childTalent : null
            }
            totalPoints={props.state.totalPoints}
            spec={item.spec}
            key={item}
          />
        );
      })}

在箭头组件内,颜色取决于Redux Dev工具和Chrome Console,但是直到我强迫它与其他UI动作重新渲染之前,它不会正确显示。

在这里,箭头从另一个动作更新状态后立即转动黄金:

我尝试在箭头组件状态和道具中将使用效率作为依赖项,但它不起作用。

箭头组件:

export const Arrow = (props) => {
  const [arrowSource, setArrowSource] = useState(null);
  const [color, setColor] = useState("silver");
  const state = props.state;

  useEffect(() => {

    switch (props.spec) {
      case "1":
        if (props.parentTalent === "1") {
          console.table(state.spec1Arrows)
          setColor(state.spec1Arrows.spec1Req1Arrow);
        } else if (props.parentTalent === "2") {
          setColor(state.spec1Arrows.spec1Req2Arrow);
        } else if (props.parentTalent === "3") {
          setColor(state.spec1Arrows.spec1Req3Arrow);
        } else if (props.parentTalent === "4") {
          setColor(state.spec1Arrows.spec1Req4Arrow);
        } else if (props.parentTalent === "5") {
          setColor(state.spec1Arrows.spec1Req6Arrow);
        } else if (props.parentTalent === "6") {
          setColor(state.spec1Arrows.spec1Req6Arrow);
        } else if (props.parentTalent === "7") {
          setColor(state.spec1Arrows.spec1Req7Arrow);
        }
        break;
      case "2":
        if (props.parentTalent === "1") {
          setColor(state.spec2Arrows.spec2Req1Arrow);
        } else if (props.parentTalent === "2") {
          setColor(state.spec2Arrows.spec2Req2Arrow);
        } else if (props.parentTalent === "3") {
          setColor(state.spec2Arrows.spec2Req3Arrow);
        } else if (props.parentTalent === "4") {
          setColor(state.spec2Arrows.spec2Req4Arrow);
        } else if (props.parentTalent === "5") {
          setColor(state.spec2Arrows.spec2Req6Arrow);
        } else if (props.parentTalent === "6") {
          setColor(state.spec2Arrows.spec2Req6Arrow);
        } else if (props.parentTalent === "7") {
          setColor(state.spec2Arrows.spec2Req7Arrow);
        }
        break;
      case "3":
        if (props.parentTalent === "1") {
          setColor(state.spec3Arrows.spec3Req1Arrow);
        } else if (props.parentTalent === "2") {
          setColor(state.spec3Arrows.spec3Req2Arrow);
        } else if (props.parentTalent === "3") {
          setColor(state.spec3Arrows.spec3Req3Arrow);
        } else if (props.parentTalent === "4") {
          setColor(state.spec3Arrows.spec3Req4Arrow);
        } else if (props.parentTalent === "5") {
          setColor(state.spec3Arrows.spec3Req6Arrow);
        } else if (props.parentTalent === "6") {
          setColor(state.spec3Arrows.spec3Req6Arrow);
        } else if (props.parentTalent === "7") {
          setColor(state.spec3Arrows.spec3Req7Arrow);
        }
        break;
      default:
        break;
    }
  }, [state, props]);

  useEffect(() => {
    switch (props.arrowType) {
      case "downSmall":
        if (color === "silver") {
          setArrowSource(downSmallSilver);
        } else if (color === "gold") {
          setArrowSource(downSmallGold);
        }
        break;
      case "downMedium":
        if (color === "silver") {
          setArrowSource(downMediumSilver);
        } else if (color === "gold") {
          setArrowSource(downMediumGold);
        }
        break;
      case "downLarge":
        if (color === "silver") {
          setArrowSource(downLargeSilver);
        } else if (color === "gold") {
          setArrowSource(downLargeGold);
        }
        break;
      case "angleArrow":
        if (color === "silver") {
          setArrowSource(angleArrowSilver);
        } else if (color === "gold") {
          setArrowSource(angleArrowGold);
        }
        break;
      case "leftArrow":
        if (color === "silver") {
          setArrowSource(leftArrowSilver);
        } else if (color === "gold") {
          setArrowSource(leftArrowGold);
        }
        break;
      case "rightArrow":
        if (color === "silver") {
          setArrowSource(rightArrowSilver);
        } else if (color === "gold") {
          setArrowSource(rightArrowGold);
        }
        break;
      default:
        console.log("No matching arrow type, check your spelling.");
    }
  }, [state, props]);

  return (
    <img
      className={props.arrowType}
      src={arrowSource}
      alt={props.arrowType}
      id={`arrwReq${props.parentTalent}Spec${props.spec}`}
    />
  );
};

So here is the flow of the components:

In the main component, I am getting the state from the redux store with useSelector hook.

const state = useSelector((state) => state);

I am rendering my button component and passing it the state to cause re-render:

<TalentButton
              imgSrc={Ferocity}
              talentName="FerocityToolTip"
              req="15"
              spec="1"
              maxPoints="5"
              playableClass="Hunter"
              state={state}
              parentTalent={["1"]}
              arrows={[
                {
                  arrowType: "downMedium",
                  color: "silver",
                  parentTalent: "1",
                  spec: "1",
                },
              ]}
              id="11"
            />

Inside the TalentButton component, it returns an array of Arrow Components in a map function. The problem is that the components inside this .map do not re-render even though the correct state is visible in react devtools.

{props?.arrows?.map((item) => {
        return (
          <Arrow
            arrowType={item.arrowType}
            parentTalent={item.parentTalent}
            childTalent={
              item?.childTalent !== undefined ? item?.childTalent : null
            }
            totalPoints={props.state.totalPoints}
            spec={item.spec}
            key={item}
          />
        );
      })}

Inside the arrow component, the color is dependent on the redux dev tools and chrome console, but it's not showing correctly until I force it to re-render with other ui actions.

stateInChromeDevTools

Here the arrow turns gold right after updating the state from another action:

enter image description here

I tried giving the useEffect inside the Arrow component state and props as dependencies but it's not working.

Arrow component:

export const Arrow = (props) => {
  const [arrowSource, setArrowSource] = useState(null);
  const [color, setColor] = useState("silver");
  const state = props.state;

  useEffect(() => {

    switch (props.spec) {
      case "1":
        if (props.parentTalent === "1") {
          console.table(state.spec1Arrows)
          setColor(state.spec1Arrows.spec1Req1Arrow);
        } else if (props.parentTalent === "2") {
          setColor(state.spec1Arrows.spec1Req2Arrow);
        } else if (props.parentTalent === "3") {
          setColor(state.spec1Arrows.spec1Req3Arrow);
        } else if (props.parentTalent === "4") {
          setColor(state.spec1Arrows.spec1Req4Arrow);
        } else if (props.parentTalent === "5") {
          setColor(state.spec1Arrows.spec1Req6Arrow);
        } else if (props.parentTalent === "6") {
          setColor(state.spec1Arrows.spec1Req6Arrow);
        } else if (props.parentTalent === "7") {
          setColor(state.spec1Arrows.spec1Req7Arrow);
        }
        break;
      case "2":
        if (props.parentTalent === "1") {
          setColor(state.spec2Arrows.spec2Req1Arrow);
        } else if (props.parentTalent === "2") {
          setColor(state.spec2Arrows.spec2Req2Arrow);
        } else if (props.parentTalent === "3") {
          setColor(state.spec2Arrows.spec2Req3Arrow);
        } else if (props.parentTalent === "4") {
          setColor(state.spec2Arrows.spec2Req4Arrow);
        } else if (props.parentTalent === "5") {
          setColor(state.spec2Arrows.spec2Req6Arrow);
        } else if (props.parentTalent === "6") {
          setColor(state.spec2Arrows.spec2Req6Arrow);
        } else if (props.parentTalent === "7") {
          setColor(state.spec2Arrows.spec2Req7Arrow);
        }
        break;
      case "3":
        if (props.parentTalent === "1") {
          setColor(state.spec3Arrows.spec3Req1Arrow);
        } else if (props.parentTalent === "2") {
          setColor(state.spec3Arrows.spec3Req2Arrow);
        } else if (props.parentTalent === "3") {
          setColor(state.spec3Arrows.spec3Req3Arrow);
        } else if (props.parentTalent === "4") {
          setColor(state.spec3Arrows.spec3Req4Arrow);
        } else if (props.parentTalent === "5") {
          setColor(state.spec3Arrows.spec3Req6Arrow);
        } else if (props.parentTalent === "6") {
          setColor(state.spec3Arrows.spec3Req6Arrow);
        } else if (props.parentTalent === "7") {
          setColor(state.spec3Arrows.spec3Req7Arrow);
        }
        break;
      default:
        break;
    }
  }, [state, props]);

  useEffect(() => {
    switch (props.arrowType) {
      case "downSmall":
        if (color === "silver") {
          setArrowSource(downSmallSilver);
        } else if (color === "gold") {
          setArrowSource(downSmallGold);
        }
        break;
      case "downMedium":
        if (color === "silver") {
          setArrowSource(downMediumSilver);
        } else if (color === "gold") {
          setArrowSource(downMediumGold);
        }
        break;
      case "downLarge":
        if (color === "silver") {
          setArrowSource(downLargeSilver);
        } else if (color === "gold") {
          setArrowSource(downLargeGold);
        }
        break;
      case "angleArrow":
        if (color === "silver") {
          setArrowSource(angleArrowSilver);
        } else if (color === "gold") {
          setArrowSource(angleArrowGold);
        }
        break;
      case "leftArrow":
        if (color === "silver") {
          setArrowSource(leftArrowSilver);
        } else if (color === "gold") {
          setArrowSource(leftArrowGold);
        }
        break;
      case "rightArrow":
        if (color === "silver") {
          setArrowSource(rightArrowSilver);
        } else if (color === "gold") {
          setArrowSource(rightArrowGold);
        }
        break;
      default:
        console.log("No matching arrow type, check your spelling.");
    }
  }, [state, props]);

  return (
    <img
      className={props.arrowType}
      src={arrowSource}
      alt={props.arrowType}
      id={`arrwReq${props.parentTalent}Spec${props.spec}`}
    />
  );
};

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

如果没有你 2025-02-19 13:11:07

从渲染到渲染,键需要保持一致。

arrows={[
  {
    arrowType: "downMedium",
    color: "silver",
    parentTalent: "1",
    spec: "1",
  },
]}

.
.
.
{props?.arrows?.map((item) => {
  .
  .
  key={item}
}

这将创建每个渲染的新参考,并可能阻止反应正确更新DOM元素,因为它不再具有相同的参考。我建议将一些ID添加到这些箭头数据点,然后将它们用作您的 Prop的值。

Keys need to be consistent from render to render.

arrows={[
  {
    arrowType: "downMedium",
    color: "silver",
    parentTalent: "1",
    spec: "1",
  },
]}

.
.
.
{props?.arrows?.map((item) => {
  .
  .
  key={item}
}

This will create a new reference each render and may be preventing React from correctly updating the DOM element as it no longer has the same reference. I would suggest adding some ID's to those arrow data points and using them as values for your key prop instead.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文