【问题标题】:Calling props.myFunction() inside a function in react functional component在反应功能组件的函数内调用 props.myFunction()
【发布时间】:2021-04-09 20:12:57
【问题描述】:

我正在将一个函数传递给 React 中的子组件,当我直接在按钮的 onClick 中调用它时,它可以完美运行。但是当我将它移到一个单独的函数中并从 onClick 调用该函数时,它不再起作用。我可以用日志语句验证正在调用的函数,但 props.myFunction() 永远不会被调用。我现在在 React 中遇到过几次这种情况,它总是让我感到困惑。

我已经查看了类似这个问题的其他一些问题,但它仍然没有帮助。

React: Can't call prop function when it is inside of another function?

此代码有效 - 当单击按钮时,它在父级中将 loggedIn 设置为 true

export default function SignupModal(props) {
  return (
    <div class="main-block">
      <button
        className="create-account-button"
        href="/"
        onClick={props.setIsLoggedIn(true)}
      >
        Create Account
      </button>
    </div>
  );
}

此代码未将loggedIn 设置为true - 但仍会调用该函数

export default function SignupModal(props) {
  const createAccount = () => {
    console.log("this gets logged");

    //but this doesn't get called
    props.setIsLoggedIn(true);
  };

  return (
    <div class="main-block">
      <button
        className="create-account-button"
        href="/"
        onClick={createAccount}
      >
        Create Account
      </button>
    </div>
  );
}

谁能告诉我为什么?

这是我在父级中尝试做的事情,可能有点不正统来呈现这样的溃败,但它是用于启动页面 - 也如前所述,它在 onClick() 中完美运行

const [isLoggedIn, setIsLoggedIn] = useState(false);

return (
  <>
    {isLoggedIn ? (
      <>
        <SearchBar onLocationChange={onLocationChange}></SearchBar>
        <NavBar></NavBar>

        <Switch>
          <Route exact path="/quik">
            <Pins
              mapRef={mapRef}
              pinnedLocationIds={pinnedLocationIds}
              pinsRemaining={pinsRemaining}
              pushPinnedLocation={pushPinnedLocation}
              usePin={usePin}
              mapCenter={mapCenter}
              setMapCenter={setMapCenter}
              matches={matches}
              setMapZoom={setMapZoom}
              mapZoom={mapZoom}
              changeStatus={changeStatus}
            />
          </Route>

          <Route path="/potentials">
            {/* dont forget, 
            the props for 'Potentials' must also pass 
            through 'potentials in the 'Pins' component! */}

            <Potentials
              pinsRemaining={pinsRemaining}
              matches={matches}
              changeStatus={changeStatus}
            />
          </Route>

          <Route path="/connects">
            <Connects matches={matches} recentMatchId={recentMatchId} />
          </Route>
          <Route path="/profile" component={Profile} />
        </Switch>
      </>
    ) : (
      <Route exact path="/quik">
        <Landing setIsLoggedIn={() => setIsLoggedIn}></Landing>
      </Route>
    )}
  </>
);

【问题讨论】:

  • setIsLoggedIn 在父组件中是什么样子的?我的猜测是它是一个返回另一个函数的函数。我这么假设是因为在第一种情况下你调用函数 立即 而在第二种情况下你直到在点击处理程序中才调用它。
  • 它只是一个 useState 变量的设置器 -- const [isLoggedIn, setIsLoggedIn] = useState(false) -- 我直接传递
  • 可以添加父组件代码吗?另外,当我说在第一种情况下您是立即调用该函数而在第二种情况下您将一个函数传递给onClick 时,您明白我的意思吗?
  • 换句话说,你确定在你点击按钮之前它没有将父状态设置为true吗?
  • 我不完全理解在第一种情况下我是如何立即调用该函数的,因为直到我按下按钮它才真正执行。

标签: reactjs components react-props


【解决方案1】:

只是为了演示您的两种情况之间的区别,举这个例子。当我在返回的 JSX 代码中立即调用一个函数时,它会在元素安装后立即触发。但是,在第二个按钮中,我必须在记录发生之前单击它。

function App() {
  return (
  <div>
    <button onClick={console.log("foo")}>Immediate log</button>
    <button onClick={() => console.log("bar")}>Must click to log</button>
  </div>
  );
}

ReactDOM.render(<App />, document.getElementById('main'));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>
<div id="main"></div>

编辑:就您的代码而言,您实际上是将setIsLoggedIn 设置为一个函数,当您将它传递给Landing 组件时,该函数会返回一个函数:

<Landing setIsLoggedIn={() => setIsLoggedIn} ></Landing>

你想要做的是:

<Landing setIsLoggedIn={setIsLoggedIn} ></Landing>

现在setIsLoggedIn 只是一个函数,您的第二个示例将起作用(您的第一个示例将立即触发,并且无法按您的预期工作)。

【讨论】:

  • 在我的情况下,当我单击按钮时,函数中的日志语句被调用,但 props.myFunciton() 不是。这就是我不明白的,为什么不呢?我可以看到它与此有关,但仍然不理解。不过谢谢
  • 所以你实际上将isLoggedIn 设置为一个返回函数的函数:&lt;Landing setIsLoggedIn={() =&gt; setIsLoggedIn} &gt;&lt;/Landing&gt; 实际上应该是&lt;Landing setIsLoggedIn={setIsLoggedIn} &gt;&lt;/Landing&gt;
  • 不知道我到底为什么这样做。不过,这是进步,非常感谢!
猜你喜欢
  • 2021-02-26
  • 2020-04-04
  • 2021-06-18
  • 1970-01-01
  • 1970-01-01
  • 2021-07-01
  • 1970-01-01
  • 2015-12-06
  • 2021-03-13
相关资源
最近更新 更多