当前位置: 首页 > 知识库问答 >
问题:

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

马边浩
2023-03-14

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

应用程序。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;

我的子组件Main Page.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
  )
};

结果:结果图像

如您所见,尽管uniqueList已经填充了数组,但uniqueType状态仍然为空。我的目标是在第一次渲染时将uniqueType初始状态设置为uniqueList。

共有1个答案

方嘉言
2023-03-14

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

UseEffect(()=>{
 // unique list update.
}, [data]);
 类似资料:
  • 我试图建立一个连接4的游戏,它有一个由7列组件组成的板组件,所有包含6个空间组件。每个列的上方都有一个拖放按钮,该按钮将用于将该件拖放到列中。为了在“红色”和“黑色”玩家之间交替,我创建了一个状态“redorblue”,它返回一个布尔值。 简而言之,当单击Drop按钮时,我希望切换“redorblue”的值,以跟踪轮到谁了。我已经将onClick函数设置为setState({redorblue:!

  • 一个组件,它呈现已填好的表单的预览,当您单击左侧的表单时,它会在右侧显示它们。 第一个handleSwitchReview向我抛出了React钩子,所呈现的钩子比上一个呈现错误时要多 第二个不是。当我控制台日志道具,例如,我得到他们4-5次时,第一个函数的视图显示,但没有第二次,第二次只显示1次在控制台日志。 尝试移动setState并在控制台中记录父组件,但这个组件是唯一一个启动了很多次并中断的

  • 我目前正在实现useSWR,以便从我的express和mongo-db后端获取数据。我能够顺利地从数据库中提取数据没有问题。下面是我用来实现这一点的代码: 然后通过以下方式访问: ,其中username是集合中的一个字段。 当我尝试将此信息添加到状态钩子中时,问题就出现了,然后状态钩子返回的错误呈现的钩子比上一次呈现的钩子要多。 删除行:和使用状态变量displayNumber的任何行就可以完全修

  • 我在jboss中部署的模块与org有依赖关系。springframework:spring orm:4.3.16。释放我没有看到任何重复的依赖项添加到类路径中。根据例外情况,我了解到我的应用程序使用一个版本成功编译,并且在部署期间引用了另一个版本。但我在任何地方都看不到任何重复版本。 有谁能帮我解决这个问题吗?请在下面找到详细的例外情况。 {“WFLYCTL0080:失败的服务”=

  • 问题内容: 我这里有一些简单的代码 每次单击按钮,控制台上都会显示2条日志,指示该组件呈现两次。 这是一个codeandbox链接,可以尝试一下。 问题答案: 呈现您的App组件的原因是在其中导致代码在严格模式下运行,并且在严格模式下,控制台显示两次,因为每个功能在开发模式下均运行两次 根据react docs: 严格模式无法自动为您检测副作用,但可以通过使其更具确定性来帮助您发现它们。这是通过有

  • null 在上面,“开始”的意思是做 任一 React-Native Run-Android 光盘android&&./Gradlew Assemblerelease 光盘.. react-native run-android--variant=release null ... ... package.json... Android/app/build.gradle