React useEffect挂钩取决于第二个效果

时间:2019-10-25 00:51:53

标签: reactjs async-await infinite-loop react-hooks use-effect

我正在使用useEffect挂钩在组件初始安装时异步获取数据。我还想使用一个效果(或另一个更适合这种情况的钩子)来转换这些数据,甚至在我的组件最初安装时也是如此。

参考上下文并初始化enhancedSections本地状态

  const displayContext = useContext(DisplayContext);
  const { sections } = displayContext;

  const schemaContext = useContext(SchemaContext);
  const { schema, getSchema } = schemaContext;

  const [enhancedSections, setEnhancedSections] = React.useState(sections);

获取装载数据(有效)

  useEffect(() => {
    async function fetchData() {
      await getSchema()
    }
    fetchData();
  }, []);

转换获取的数据,然后setEnhancedSections
这里的问题是schema仍然为空

  useEffect(() => {
      let newSectionsArr = [];
      const schemaData = schema.data; //schema hasn't fetched yet
      Object.entries(sections).forEach(section => {
        let sectionKey = section[0];
        for(var i = 1; i < section.length; i++){
          section[i].forEach(item => {
            let table = schemaData.find(table => table[item.definition.table_name]);
            if (table) {
              let obj = table[item.definition.table_name].columns.find(column => column.field === item.definition.field_name);
              if (obj) {
                item.definition.description = obj.description;
                item.section = sectionKey;
                newSectionArr.push(item);
              }
            }
           setEnhancedSections(newSectionArr); // infinite loop...different problem
          });
        }
      });
  }, []);

当我将上述内容从useEffect中取出并放入基本的if语句中时,它起作用了(无限循环仍然是一个问题)...

 if(schema && sections){
      let newSectionArr = [];
       ...
    }

我了解我应该根据React文档使用多种效果来分离关注点,但是我不确定如何使一种效果“等待”另一种效果。

谢谢您的帮助。

1 个答案:

答案 0 :(得分:1)

第二部分不必位于setEnhancedState中,只需从您的现有状态派生即可。您正在调用enhancedState,从而陷入无限循环,但是const displayContext = useContext(DisplayContext); const { sections } = displayContext; const schemaContext = useContext(SchemaContext); const { schema, getSchema } = schemaContext; // No need for redundant enhancedSections state useEffect(() => { async function fetchData() { await getSchema() } fetchData(); }, []); let enhancedSections = []; const schemaData = schema ? schema.data : []; Object.entries(sections).forEach(section => { let sectionKey = section[0]; for(var i = 1; i < section.length; i++){ section[i].forEach(item => { let table = schemaData.find(table => table[item.definition.table_name]); if (table) { let obj = table[item.definition.table_name].columns.find(column => column.field === item.definition.field_name); if (obj) { item.definition.description = obj.description; item.section = sectionKey; enhancedSections.push(item); } } }); } }); // Use enhancedSections as you need now 是派生的,不需要在状态本身中存在。您的最终组件可能看起来像这样:

{{1}}