【问题标题】:How to call Parent function with useState Hook in React?如何在 React 中使用 useState Hook 调用 Parent 函数?
【发布时间】:2019-07-19 06:31:37
【问题描述】:

理想的结果是在单击列表中的项目时显示字符串。

这是根组件。

const App = () => {
  const [click, setClick] = useState(null);
  const handleClick = name => {
    setClick(name);
  };
  return (
    <div>
      <Parent handleClick={handleClick} />
      {click && <p>{click} is clicked.</p>}
    </div>
  );
};

和父组件。

const Parent = ({ handleClick }) => (
  <div>
    <Child
      name="First Item"
      handleClick={handleClick("First Item is Clicked!")}
    />
    <Child
      name="Second Item"
      handleClick={handleClick("Second Item is Clicked!")}
    />
    <Child
      name="Third Item"
      handleClick={handleClick("Third Item is Clicked!")}
    />
  </div>
);

和子组件。

const Child = ({ name, handleClick }) => <li onClick={handleClick}>{name}</li>;

还有代码沙箱link

我只是想知道为什么结果永远不会被点击改变。

【问题讨论】:

    标签: reactjs ecmascript-6 react-hooks


    【解决方案1】:

    问题是您没有将函数传递给handleClick,而是从父级传递一个评估值。你的代码必须是

    import React from "react";
    import Child from "./Child";
    
    const Parent = ({ handleClick }) => (
      <div>
        <Child
          name="First Item"
          handleClick={() => handleClick("First Item is Clicked!")}
        />
        <Child
          name="Second Item"
          handleClick={() => handleClick("Second Item is Clicked!")}
        />
        <Child
          name="Third Item"
          handleClick={() => handleClick("Third Item is Clicked!")}
        />
      </div>
    );
    
    export default Parent;
    

    Working demo

    【讨论】:

      【解决方案2】:

      您正在调用handleClick() 函数,而不是将函数传递给子组件。使用内联箭头函数来包装调用。

      注意:因为每当渲染父级时都会重新创建箭头函数,如果您有很多项目,或者由于其他原因不断渲染父级,这可能会导致性能问题。

      const { useState } = React;
      
      const App = () => {
        const [click, setClick] = useState(null);
        const handleClick = name => {
          setClick(name);
        };
        return (
          <div>
            <Parent handleClick={handleClick} />
            {click && <p>{click} is clicked.</p>}
          </div>
        );
      };
      
      const Parent = ({ handleClick }) => (
        <div>
          <Child
            name="First Item"
            handleClick={() => handleClick("First Item is Clicked!")}
          />
          <Child
            name="Second Item"
            handleClick={() => handleClick("Second Item is Clicked!")}
          />
          <Child
            name="Third Item"
            handleClick={() => handleClick("Third Item is Clicked!")}
          />
        </div>
      );
      
      const Child = ({ name, handleClick }) => <li onClick={handleClick}>{name}</li>;
      
      ReactDOM.render(
        <App />,
        root
      )
      <script crossorigin src="https://unpkg.com/react@16/umd/react.development.js"></script>
      <script crossorigin src="https://unpkg.com/react-dom@16/umd/react-dom.development.js"></script>
      
      <div id="root"></div>

      另一种解决方案是将函数和文本都传递给子组件,并让它处理函数调用。在这种情况下,您可以使用useCallback 来记忆函数:

      const { useState, useCallback } = React;
      
      const App = () => {
        const [click, setClick] = useState(null);
        const handleClick = name => {
          setClick(name);
        };
        return (
          <div>
            <Parent handleClick={handleClick} />
            {click && <p>{click} is clicked.</p>}
          </div>
        );
      };
      
      const Parent = ({ handleClick }) => (
        <div>
          <Child
            name="First Item"
            handleClick={handleClick} text="First Item is Clicked!"
          />
          <Child
            name="Second Item"
            handleClick={handleClick} text="Second Item is Clicked!"
          />
          <Child
            name="Third Item"
            handleClick={handleClick} text="Third Item is Clicked!"
          />
        </div>
      );
      
      const Child = ({ name, handleClick, text }) => {
        const handler = useCallback(() => handleClick(text), [handleClick, text]);
        
        return <li onClick={handler}>{name}</li>;
      }
      
      ReactDOM.render(
        <App />,
        root
      )
      <script crossorigin src="https://unpkg.com/react@16/umd/react.development.js"></script>
      <script crossorigin src="https://unpkg.com/react-dom@16/umd/react-dom.development.js"></script>
      
      <div id="root"></div>

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2021-04-03
        • 2021-11-27
        • 2020-03-08
        • 1970-01-01
        • 2019-10-21
        • 2022-01-02
        • 2020-03-18
        • 2019-09-14
        相关资源
        最近更新 更多