![](/img/trans.png)
[英]react native hooks can only be called inside body of a function component
[英]React Hooks can only be called inside the body of a function component
如何在按钮单击时触发useEffect()
,而不是在渲染组件时触发?
当我在这样的函数中使用它时,我得到一个错误说明:
钩子只能在函数组件的主体内部调用
function App() {
function buttonClicked() {
useEffect(() => {
// Fetch from API
});
}
return (
<div className="App">
<header className="App-header">
<img src={logo} className="App-logo" alt="logo" />
<h1 className="App-title">App Title</h1>
</header>
<p className="App-intro">
To get started, edit <code>src/App.js</code> and save to reload.
</p>
<button onClick={buttonClicked}>Make API Call</button>
</div>
);
}
接受的答案并不完全正确IMO。 如果您的目标是在单击按钮时触发数据提取,则无需使用useEffect
。 useEffect
用于替换生命周期钩子 - componentDidMount
, componentDidUpdate
和componentWillUnmount
。
想想这个 - 没有钩子,你需要这些生命周期钩子来实现你想要的吗? 使用类,您只需使用this.state
和单击按钮时触发的回调; 你不会使用任何这些生命周期钩子。
您想要实现的副作用是数据提取,但这是用户触发的效果,而useEffect
在这里没有用。 useEffect
仅在您希望在组件的生命周期中产生副作用时才有用。
下面的代码应该用钩子做你想要的,而你不需要useEffect
,你只需要useState
。
function App() { const [user, setUser] = React.useState(null); function fetchData() { fetch('https://randomuser.me/api/') .then(results => results.json()) .then(data => { setUser(data.results[0]); }); }; return <div> <p>{user ? user.name.first : 'No data'}</p> <button onClick={fetchData}>Fetch Data</button> </div>; } ReactDOM.render(<App/>, document.getElementById('app'));
<script src="https://unpkg.com/react@16.7.0-alpha.0/umd/react.development.js"></script> <script src="https://unpkg.com/react-dom@16.7.0-alpha.0/umd/react-dom.development.js"></script> <div id="app"></div>
听起来你误解了useEffect
的用法。 它就像componentDidUpdate
钩子一样 - 它根据值的变化而被触发,而不是直接由某个函数触发。 调用render
方法时,也会调用useEffect
。 很难说你的目标是什么,但是从你的片段来看,最有意义的就是在没有任何钩子的情况下调用fetch
。 但是要回答你的问题,触发useEffect
一种方法是更新你的状态,你可以创建useEffect
钩子,只有在特定属性的值被改变时才被触发:
const [buttonClicked, setButtonClicked] = useState(false);
useEffect(() => {
// Fetch from API
}, [buttonClicked]);
<button onClick={() => setButtonClicked(true)}>Make API Call</button>
现在当你点击时,应该触发useEffect
,但是因为你添加了, [buttonClicked]
,如果任何其他属性值改变,它将不会被调用。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.