如何将Set[State]函数传递给非派生触发器组件

yruzcnhs  于 2022-10-15  发布在  React
关注(0)|答案(2)|浏览(138)

bounty 6天后到期。这个问题的答案有资格获得+50的声誉奖励。cdhit想要引起更多的关注这个问题:1.提供一个比现在更好的实际解决方案2.如果不可能,带上不可能的原因/根本原因,为了实现所以利用内部React实现的知识,需要知道React的核心。

这是图表。ChildComponentB有一个状态-stateX。在ChildComponentA中,一旦事件发生,它将更改ChildComponentB中的状态X。
如果ChildComponentB是ChildComponentA的子组件,则只需将setStateX作为道具传递给ChildComponentA即可。但在这种情况下,情况并非如此。

实际情况如下所示。我有一个画布组件,那里已经有一些静态矩形,一旦鼠标移动到矩形的线上,我想将指示线添加到画布组件的另一个子组件中。
因此,rectComponent不是DistanceIndicator sComponent的后代。所以我不能将setLines传递给RectComponent。
你是如何做到这一点的?

如果我使用useContext方法,它会起作用吗?
感谢@KonradLinkowski为您提供解决方案。以下是他的代码。然而,useContext仍然将状态提升到ParentComponent。

import React, { useContext, createContext, useState } from "react";

const Context = createContext();

function ChildComponentA(props) {
  const { setStateX } = useContext(Context);

  return (
    <div>
      componentA button:{" "}
      <button onClick={() => setStateX((i) => i + 1)}>add</button>
    </div>
  );
}

function ChildComponentB(props) {
  const { stateX } = useContext(Context);

  return <div> stateX is {stateX} </div>;
}

export default function ParentComponent(props) {
  const [stateX, setStateX] = useState(0);
  return (
    <>
      <Context.Provider value={{ stateX, setStateX }}>
        <ChildComponentA> </ChildComponentA>
        <ChildComponentB> </ChildComponentB>
      </Context.Provider>
    </>
  );
}

关于组件B的可重用性,即在此场景中的距离指示器组件,它包括JSX和状态,以及在其中有更改状态的逻辑的接口。这些都是未来应该重复使用的部件。
从OOP的Angular 来看,行(STATE)属于DistanceIndicatorsComponent,而如何更改行(在本例中为Add Line)也应该是属于DistanceIndicator sComponent的可复用逻辑。
然而,从React的Angular 来看,从OOP的Angular 来看,提升setLines(这是在某个事件下触发的接口)还不够好。将状态行和状态管理函数setLines提升到CanvesComponent,就封装而言是“不够好”。将 Package 组件放在ComponentB的顶部是相同的事情,setLines仍然不能被传递给FrameComponent,除非FrameComponent是 Package 组件的子组件。
非常常见的情况是,顶部有一个非常重的组件来容纳所有的状态和事件。这让我觉得这是一个糟糕的一小部分代码。组件的可重用性应该基于一组组件,在这组组件中,顶部有一个非受控组件,而这个非受控组件的下面是受控组件。这组组件是一个“外部”可重用性单元。
在这里,在这个图表中,应该有不止一个可重用单元,而不是一个。如果将状态提升到CanvesComponent,则会使下面的所有组件都不可重复使用。在某种程度上,您仍然可以重用该组件的JSX,但我想说,在可重用性方面,它应该包含尽可能多的可重用逻辑。
我可能错了,请纠正我。感谢您分享您的宝贵意见。

感谢您投票结束此问题。但我不知道这背后的合理性。

对我来说,这个问题没有得到很好的回答。

798qvoo8

798qvoo81#

如果在ParentComponent中保留共享状态是个问题,您可以将Context.Provider提取到一个单独的组件,并将组件作为其子组件传递,这些子组件可以通过useContext挂钩访问上下文值。

function ParentContextProvider({ children }) {
  const [stateX, setStateX] = useState(0);

  return (
    <Context.Provider value={{ stateX, setStateX }}>
      {children}
    </Context.Provider>
  );
}

export default function ParentComponent(props) {
  return (
    <ParentContextProvider>
      <ChildComponentA />
      <ChildComponentB />
    </ParentContextProvider>
  );
}

现在,您可以向ParentContextProvider添加任何新的状态/setState,并可以将其传递给它的子级

igetnqfo

igetnqfo2#

你看过Redux商店吗?您可以有一个像“showLine”或“OriginX”/“OriginY”这样的变量,然后让一个子级调度更改,而另一个子级则使用选择器来表示值?
您是否知道Redux是否适用于您的用例?

相关问题