【问题标题】:Why my react app rendered twice and give me an empty array in first render when I'm trying fetching API?当我尝试获取 API 时,为什么我的反应应用程序渲染了两次并在第一次渲染时给了我一个空数组?
【发布时间】:2021-07-16 06:17:32
【问题描述】:

第二次渲染成功,但副作用是我的子组件使用其父组件的上下文值作为初始状态(使用 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。

【问题讨论】:

    标签: javascript reactjs use-effect use-context use-reducer


    【解决方案1】:

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

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

    【讨论】:

    • 好的,谢谢@Medi,但为什么要渲染两次?
    • @Sedana 您正在执行异步操作,该操作会更新状态并导致第二次重新渲染。
    猜你喜欢
    • 1970-01-01
    • 2020-10-01
    • 2021-06-04
    • 1970-01-01
    • 1970-01-01
    • 2021-12-06
    • 2020-09-07
    • 2022-10-02
    相关资源
    最近更新 更多