React Hooks 只能在函数组件内部调用
React Hooks can only be called inside the body of a function component
如何在单击按钮而不是渲染组件时触发 useEffect()
?
当我在这样的函数中使用它时,我收到一条错误消息:
Hooks can only be called inside the body of a function component
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>
);
}
听起来你误解了 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]
,如果任何其他属性值改变,它不会被调用。
如果您的目标是在单击按钮时触发数据获取,则不需要 useEffect
。 useEffect
用于替换生命周期挂钩 - componentDidMount
、componentDidUpdate
和 componentWillUnmount
.
想一想 - 如果没有钩子,你是否需要这些生命周期钩子来实现你想要的?使用 类,您只需使用 this.state
和点击按钮时触发的回调;您不会使用这些生命周期挂钩中的任何一个。
您想要实现的副作用是数据获取,但这是用户触发的效果,useEffect
在这里没有帮助。 useEffect
仅当您希望在组件的生命周期中产生副作用时才有用。
下面的代码应该可以实现你想用hooks实现的功能,不需要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()
?
当我在这样的函数中使用它时,我收到一条错误消息:
Hooks can only be called inside the body of a function component
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>
);
}
听起来你误解了 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]
,如果任何其他属性值改变,它不会被调用。
如果您的目标是在单击按钮时触发数据获取,则不需要 useEffect
。 useEffect
用于替换生命周期挂钩 - componentDidMount
、componentDidUpdate
和 componentWillUnmount
.
想一想 - 如果没有钩子,你是否需要这些生命周期钩子来实现你想要的?使用 类,您只需使用 this.state
和点击按钮时触发的回调;您不会使用这些生命周期挂钩中的任何一个。
您想要实现的副作用是数据获取,但这是用户触发的效果,useEffect
在这里没有帮助。 useEffect
仅当您希望在组件的生命周期中产生副作用时才有用。
下面的代码应该可以实现你想用hooks实现的功能,不需要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>