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
我正在使用 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