在 React Hooks 中通信组件的简单而正确的方法是啥?

Posted

技术标签:

【中文标题】在 React Hooks 中通信组件的简单而正确的方法是啥?【英文标题】:What is the easy and proper way of communicating components in React Hooks?在 React Hooks 中通信组件的简单而正确的方法是什么? 【发布时间】:2020-12-06 11:53:13 【问题描述】:

在学习了一周的 React 并深入研究 React Hooks 之后,我偶然发现了组件之间的通信问题,如下所示:

父母对孩子 子到父 孩子对孩子(兄弟姐妹)

我能够通过添加一个名为 onChange 的 prop 并传递一个在其父级上定义的函数,从一个子级与它自己的父级进行通信。

所以这就是我在父级中所拥有的:

function handleChange(val: any) 
    console.log(val)
    console.log(hiddenPiece)


return ( 
    <div className="board-inner">
        puzzlePieces
    </div>
)

这是孩子

props.onChange(props.index);

真正的问题是,在点击状态之后或当孩子的状态发生变化时,我如何能够从父母直接与其孩子沟通?我一直在寻找简单的样本,但我想我现在不擅长我的研究。我需要有人可以通过明确的例子帮助我。感谢您抽出宝贵时间来帮助我。

【问题讨论】:

使用一种状态管理框架,例如:redux 考虑 React.Context 或 redux.js、recoil.js、rematch.js ... 【参考方案1】:

这是您描述的两种情况(父>子和子>父)的一个非常基本的示例。父母持有状态,有一些修改它的功能,并呈现两个孩子。

https://codesandbox.io/s/silly-browser-y9hdt?file=/src/App.tsx

const Parent = () => 
  const [counter, setCounter] = useState<number>(1);

  const handleIncrement = () => 
    setCounter((prevCount) => prevCount + 1);
  ;

  const handleDecrement = () => 
    setCounter((prevCount) => prevCount - 1);
  ;

  // used as prop with the children
  const doubleTheCounter = () => 
    setCounter((prevCount) => prevCount * 2);
  ;

  return (
    <div>
      <h1>Parent counter</h1>
      <p>counter</p>
      <button onClick=handleIncrement>+</button>
      <button onClick=handleDecrement>-</button>
      <ChildTriple countFromParent=counter />
      <DoubleForParent doubleCallback=doubleTheCounter />
    </div>
  );
;

第一个子节点从父节点接收状态并使用显示不同的东西(在本例中为“三重”):

type ChildTripleProps =  countFromParent: number ;

// Receives count state as prop
const ChildTriple = ( countFromParent : ChildTripleProps) => 
  const [tripleCount, setTripleCount] = useState<number>(countFromParent * 3);

  useEffect(() => 
    setTripleCount(countFromParent * 3);
  , [countFromParent]);

  return (
    <div>
      <h1>Child triple counter</h1>
      <p>tripleCount</p>
    </div>
  );
;

第二个孩子收到来自父母的回调函数,改变父母的状态:

type DoubleForParentProps =  doubleCallback: () => void ;

// Receives a function as prop, used to change state of the parent
const DoubleForParent = ( doubleCallback : DoubleForParentProps) => 
  const handleButtonClick = () => 
    doubleCallback();
  ;

  return (
    <div>
      <h1>Child double counter</h1>
      <button onClick=handleButtonClick>Double the parent count</button>
    </div>
  );
;

对于您的第三种情况(孩子 孩子),有很多不同的选择。第一个显然在其父级中保持状态并将其传递给两个子级,类似于本示例中的父级。

如果您有孙子或组件在树中的距离更远,那么使用某种状态管理解决方案可能是有意义的。大多数时候,内置的React context 是完全足够的。如果您想了解有关上下文的最佳实践,我强烈推荐 Kent C. Dodds' blog post。这也将帮助您更好地了解 React 生态系统。

在我看来,外部状态库是 a) too complex as a beginner、b) really new and not battle proven 或 c) not a best practice anymore or overblown。

【讨论】:

以上是关于在 React Hooks 中通信组件的简单而正确的方法是啥?的主要内容,如果未能解决你的问题,请参考以下文章

React Hooks用法与实战

React Hooks用法与实战

React Hooks用法与实战

为何要使用React Hooks?

React拓展 - setState - 路由组件懒加载 - Hooks - Fragment - Context - PureComponent - 插槽 - 错误边界 - 组件通信方式总结(代码片

在 React 中,一个类组件可以是无状态的,而现在使用 Hooks 一个函数组件可以是有状态的吗?