有同样的问题。我不知道他们为什么不在文档中提及这一点。只想对 Tobias Haugen 的回答补充一点。
要在每个组件/父级重新渲染中运行,您需要使用:
  useEffect(() => {
    // don't know where it can be used :/
  })
要在组件安装后仅运行一次(将呈现一次),您需要使用:
  useEffect(() => {
    // do anything only one time if you pass empty array []
    // keep in mind, that component will be rendered one time (with default values) before we get here
  }, [] )
要在组件安装和 data/data2更改时运行任何一次:
  const [data, setData] = useState(false)
  const [data2, setData2] = useState('default value for first render')
  useEffect(() => {
// if you pass some variable, than component will rerender after component mount one time and second time if this(in my case data or data2) is changed
// if your data is object and you want to trigger this when property of object changed, clone object like this let clone = JSON.parse(JSON.stringify(data)), change it clone.prop = 2 and setData(clone).
// if you do like this 'data.prop=2' without cloning useEffect will not be triggered, because link to data object in momory doesn't changed, even if object changed (as i understand this)
  }, [data, data2] )
我大部分时间是如何使用它的:
export default function Book({id}) { 
  const [book, bookSet] = useState(false) 
  const loadBookFromServer = useCallback(async () => {
    let response = await fetch('api/book/' + id)
    response  = await response.json() 
    bookSet(response)
  }, [id]) // every time id changed, new book will be loaded
  useEffect(() => {
    loadBookFromServer()
  }, [loadBookFromServer]) // useEffect will run once and when id changes
  if (!book) return false //first render, when useEffect did't triggered yet we will return false
  return <div>{JSON.stringify(book)}</div>  
}