当我尝试获取 API 时,为什么我的 React 应用程序渲染了两次并在第一次渲染时给我一个空数组?

Why my react app rendered twice and give me an empty array in first render when I'm trying fetching API?

第二次渲染成功,但副作用是我的子组件使用其父组件的上下文值作为 initialState(使用 useState 挂钩)将其初始状态设置为空数组。我正在使用 React Hooks(useState、useContext、useReducer、useEffect)

App.js:

...
export const MainContext = React.createContext();

const initialState = {
  data: [],
};

const reducer = (state, action) => {
  switch (action.type) {
    case "ADD_LIST":
      return { ...state, data: action.payload };
    default:
      return state;
  }
};

function App() {
  const [dataState, dispatch] = useReducer(reducer, initialState);
  const fetchData = () => {
    axios
      .get("http://localhost:3005/data")
      .then((response) => {
        const allData = response.data;
        if (allData !== null) {
          dispatch({ type: "ADD_LIST", payload: allData });
        }
      })
      .catch((error) => console.error(`Error: ${error}`));
  };

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

  console.log("useReducer", dataState); //LOG 1

  return (
    <div>
      <MainContext.Provider
        value={{ dataState: dataState, dataDispatch: dispatch }}
      >
        <MainPage />
      </MainContext.Provider>
    </div>
  );
}
export default App;

我的子组件 MainPage.jsx

...
function MainPage() {
  const mainContext = useContext(MainContext);
  const data = mainContext.dataState.data;
  const uniqueList = [...new Set(data.map((list) => list.type))];
  console.log("uniqueList", uniqueList); // LOG 2
  const [uniqueType, setUniqueType] = useState(uniqueList);
  console.log("uniqueType State", uniqueType); // LOG 3
  const catAlias = {
    account: "Account",
    commandLine: "Command",
    note: "Note",
    bookmark: "Bookmark",
  };
  return (
  // jsx code, not necessary with the issue
  )
};

结果: result image

如您所见,uniqueType 状态仍然为空,尽管 uniqueList 已经填充了数组。我的目标是使 uniqueType 初始状态从第一次渲染到 uniqueList。

这是预期的行为。用于状态初始化的值仅在第一次渲染时使用。在后续渲染中,组件需要使用 useEffect 来跟踪值的变化。

UseEffect(()=>{
 // unique list update.
}, [data]);