React useEffect 钩子依赖于第二个效果

React useEffect hook dependent on a second 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 此时仍然为 null

  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 文档使用多种效果来分离关注点,但我不确定如何使一种效果 "await" 成为另一种效果。

感谢您的帮助。

第二部分不需要在 useEffect 中,它只是从您现有的状态派生而来。你正在打一个无限循环,因为你正在调用 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