使用 React Hooks 快速解释状态管理

Quick explanation of state management with react hooks

我刚开始使用 React Hooks,我有一个快速的问题。我可以声明吗 const [page] = useState(1); 而不是 const [page, setPage] = useState(1); 而根本不调用 setPage?我问的原因是因为我看到使用 setPage 会导致使用当前代码不必要地呈现页面。请看一下,您还可以在此处查看工作示例并进行修改:https://uqdil.csb.app/

import axios from "axios";
import { useState, useEffect } from "react";

export default function App() {
  const [userData, setUserData] = useState([]);
  const [page, setPage] = useState(1);

  const getUserData = async (page) => {
    try {
      const url = `https://randomuser.me/api?page=${page}`;
      const response = await axios.get(url);
      setUserData([...userData, ...response.data.results]);
    } catch (error) {
      console.log("error >> ", error);
    }
  };

  const getUser = (page = 1) => {
    setPage(page);
    getUserData(page);
  };

  useEffect(() => {
    getUser();
  }, []);

  const getUserName = (user) => {
    const {
      name: { first, last }
    } = user;
    return `${first} ${last}`;
  };

  const getImagUrl = (user) => {
    const {
      picture: { large }
    } = user;
    return `${large}`;
  };

  if (!userData) {
    return <p>Loading user data ... </p>;
  }
  return (
    <div className="App">
      {userData.map((user, idx) => {
        const userName = getUserName(user);
        return (
          <div key={idx} style={{ marginTop: "20px" }}>
            <img alt={userName} src={getImagUrl(user)} />
            <p>User Name: {userName}</p>
          </div>
        );
      })}
      <button
        onClick={() => {
          getUser(page + 1);
        }}
      >
        Load More
      </button>
    </div>
  );
}

Can I just declare const [page] = useState(1); instead of const [page, setPage] = useState(1); and not call setPage at all?

如果你不想改变状态,那么是的,你可以只解构数组的元素0。不过这种情况很少见,因为通常使用状态变量的原因是您希望它能够改变。

关于我能想到的创建一个永远不会改变的状态的唯一原因是你有一些改变超出你控制的值,你想记住第一次渲染时的值。由于 useState 的默认值仅在第一次渲染时使用,useState 有点让你这样做:

const Example = ({ propThatMayChange }) => {
  const [initialValue] = useState(propThatMayChange);

  // ...
}

也可以使用 ref 实现同样的效果,但由于它是一个可变对象,原则上有人可能会更改它:

const Example = ({ propThatMayChange }) => {
  const initialValueRef = useRef(propThatMayChange);

  // ...
}

可以,如果您不想更改页面。 现在这不是您遇到的问题。 只要您不在 HTML 中包含 page,当您 setPage 时就不会重新渲染任何内容 您还可以在 function App 之上包含 var page 并根据需要修改它而不触发更新。

但在这种情况下,这将毫无意义。

请参阅下文如何修改您的代码。

import axios from "axios";
import {
  useState,
  useEffect
} from "react";

export default function App() {
  const [userData, setUserData] = useState([]);
  const [page, setPage] = useState(1);

  const getUserData = async() => {
    try {
      const url = `https://randomuser.me/api?page=${page}`;
      const response = await axios.get(url);
      setUserData([...userData, ...response.data.results]);
    } catch (error) {
      console.log("error >> ", error);
    }
  };

  const nextPage = () => {
    setPage(page + 1);
  }

  useEffect(() => {
    getUserData();
  }, []);

  useEffect(() => {
    getUserData(); // when page is changed then get users
  }, [page]);

  const getUserName = (user) => {
    const {
      name: {
        first,
        last
      }
    } = user;
    return `${first} ${last}`;
  };

  const getImagUrl = (user) => {
    const {
      picture: {
        large
      }
    } = user;
    return `${large}`;
  };

  if (!userData) {
    return <p > Loading user data... < /p>;
  }
  return ( <
    div className = "App" > {
      userData.map((user, idx) => {
        const userName = getUserName(user);
        return (<div key = {
            idx
          }
          style = {
            {
              marginTop: "20px"
            }
          }>
          <img alt = {
            userName
          }
          src = {
            getImagUrl(user)
          }/> 
          <p> User Name: {
            userName
          } </p> 
          </div>
        );
      })
    } 
    <button onClick={nextPage}>
    Load More 
    </button> 
    </div>
  );
}