提取数据后设置状态的问题(React挂钩)

时间:2020-04-17 20:27:08

标签: javascript reactjs fetch react-hooks state

我正在使用API​​并制作了一个react应用来显示数据。 发送请求信息(通过表单)(通过axios)后,我使用React Hooks的setState方法设置了状态,但是效果不是很好,这会导致罕见的行为。我知道我应该使用“效果”功能,但我不知道如何使用。

这是我设置状态的代码部分:

function Home() {
  const [search, setSearch] = useState('')
  const [visibleMsj, setVisibleMsj] = useState(false)
  const [pokemon, setPokemon] = useState({})

  const handleSearch = async (e) => {
    e.preventDefault();
    if(search === ''){
      setVisibleMsj(true)
    } else {
      setVisibleMsj(false)
      searchForPokemon()
    }
  };

  const searchForPokemon = async () => {
    const res = await getPokemon(search)
    setPokemon(res)
    console.log(pokemon)
  }

这是发送请求的功能(在另一个文件中):

import axios from "axios";

const getPokemon = async (name) => {
  return await axios
    .get(`https://pokeapi.co/api/v2/pokemon/${name}`)
    .then(function (response) {
      return response.data;
    })
    .catch(function (err) {
      console.log(err);
    });
};

export { getPokemon };

最后是提交事件中执行该方法的表单:

<Form onSubmit={handleSearch} id="form">
          <Form.Field>
            <Form.Input
              icon="search"
              placeholder="Search by name or id..."
              name="pokemon"
              onChange={(event) => setSearch(event.target.value)}
              value={search}
            />
          </Form.Field>
</Form>

但是在控制台中,当我发送请求时我得到了这个: Console in web browser

那么,状态发生了什么?另外,我需要在表单下方(内部渲染)中显示状态变量“ pokemon”的属性,并且我无法获取这些属性,可能是因为安装时的第一个值是{}?。

谢谢。

2 个答案:

答案 0 :(得分:0)

仅当状态中的特定值更改时才需要调用api。您可以使用useEffect对这些更改做出反应,它接受第二个数组参数,您可以在其中添加要在状态更改时做出反应的状态值。

function Home() {
    const [search, setSearch] = useState('')
    const [visibleMsj, setVisibleMsj] = useState(false)
    const [pokemon, setPokemon] = useState({})

    useEffect(() => {
       if(search === ''){
         setVisibleMsj(() => true)
       } else {
          setVisibleMsj(() => false)
          searchForPokemon()
       }
    },[search])

   const searchForPokemon = async () => {
      const res = await getPokemon(search)
      setPokemon(() => res)
   }

   ...

}

侧面注意:我建议您在设置状态下使用功能模式。 React批处理状态更新。使用功能可确保您始终获得最新更新 例如:setState((prevState) => prevState + 1)

答案 1 :(得分:0)

您还可以将数据获取功能放在useCallback挂钩上,因此仅当[...]中指定的状态更新时,回调才会更改。然后,您可以将该回调传递给useEffect挂钩。您不能仅将常规回调传递给useEffect的依赖项列表,因为它将更改每个渲染,因此useEffect挂钩也将在每个渲染上触发。

`const fetchData = useCallback(() => YourAsyncFunction, [variables, that, change, in that function]);

const useEffect(() => {
//this will fire only when fetchData gets updated
fetchData();
}, fetchData);

`