如何像这样使用useState?这是什么意思?

Vij*_*Sai 1 prefetch rerender reactjs react-hooks

谁能解释一下const rerender = React.useState(0)[1]这是什么?

import React from 'react'
import axios from 'axios'
import {
  useQuery,
  useQueryClient,
  QueryClient,
  QueryClientProvider,
} from "@tanstack/react-query"
import { ReactQueryDevtools } from "@tanstack/react-query-devtools"

const getCharacters = async () => {
  await new Promise((r) => setTimeout(r, 500))
  const { data } = await axios.get('https://rickandmortyapi.com/api/character/')
  return data
}

const getCharacter = async (selectedChar) => {
  await new Promise((r) => setTimeout(r, 500))
  const { data } = await axios.get(
    `https://rickandmortyapi.com/api/character/${selectedChar}`,
  )
  return data
}

const queryClient = new QueryClient()

export default function App() {
  return (
    <QueryClientProvider client={queryClient}>
      <Example />
    </QueryClientProvider>
  )
}

function Example() {
  const queryClient = useQueryClient()
  **const rerender = React.useState(0)[1]**
  const [selectedChar, setSelectedChar] = React.useState(1)

  const charactersQuery = useQuery(['characters'], getCharacters)

  const characterQuery = useQuery(['character', selectedChar], () =>
    getCharacter(selectedChar),
  )

  return (
    <div className="App">
      <p>
        Hovering over a character will prefetch it, and when it's been
        prefetched it will turn <strong>bold</strong>. Clicking on a prefetched
        character will show their stats below immediately.
      </p>
      <h2>Characters</h2>
      {charactersQuery.isLoading ? (
        'Loading...'
      ) : (
        <>
          <ul>
            {charactersQuery.data?.results.map((char) => (
              <li
                key={char.id}
                onClick={() => {
                  setSelectedChar(char.id)
                }}
                onMouseEnter={async () => {
                  await queryClient.prefetchQuery(
                    ['character', char.id],
                    () => getCharacter(char.id),
                    {
                      staleTime: 10 * 1000, // only prefetch if older than 10 seconds
                    },
                  )

                  setTimeout(() => {
                    **rerender({})**
                  }, 1)
                }}
              >
                <div
                  style={
                    queryClient.getQueryData(['character', char.id])
                      ? {
                          fontWeight: 'bold',
                        }
                      : {}
                  }
                >
                  {char.id} - {char.name}
                </div>
              </li>
            ))}
          </ul>

          <h3>Selected Character</h3>
          {characterQuery.isLoading ? (
            'Loading...'
          ) : (
            <>
              <pre>{JSON.stringify(characterQuery.data, null, 2)}</pre>
            </>
          )}
          <ReactQueryDevtools initialIsOpen />
        </>
      )}
    </div>
  )
}
Run Code Online (Sandbox Code Playgroud)

我想知道这意味着什么,我无法理解这种 useState 语法,我从未见过这种类型的语法。有人可以分享一些关于这个的事情吗?

Dan*_*elJ 5

useState有两部分:值和更新值的函数。

看一下下面的代码片段,它解释了 useState 钩子如何正常分配值。

  var fruitStateVariable = useState('banana'); // Returns a pair
  var fruit = fruitStateVariable[0]; // The value of the state
  var setFruit = fruitStateVariable[1]; // A asynchronous function to update the state.
Run Code Online (Sandbox Code Playgroud)

通过访问索引为 1 的项目,您将分配 rerender 一个函数来更新状态,这将触发重新渲染,因为 React 看到的值来自0-> {}

至于代码为什么这样做,作者似乎试图绕过useState异步更新这不是一个好的模式,应该避免!。正如您所说,您以前没有见过这种语法,因为它不是触发函数重新渲染的适当方法。

如果你确实需要强制重新触发,React Docs推荐这种方式:

  var fruitStateVariable = useState('banana'); // Returns a pair
  var fruit = fruitStateVariable[0]; // The value of the state
  var setFruit = fruitStateVariable[1]; // A asynchronous function to update the state.
Run Code Online (Sandbox Code Playgroud)

但此资源的关键内容是尽可能避免这种模式。