[英]React Hook "useState" is called inside condition, but not condition is inside
After to read this page: https://typeofnan.dev/fix-the-react-hook-is-called-conditionally-error-in-react/阅读此页面后: https://typeofnan.dev/fix-the-react-hook-is-called-conditionally-error-in-react/
I try to find the error but i keep getting the error:我试图找到错误,但我不断收到错误:
React Hook "useState" is called conditionally有条件地调用 React Hook “useState”
here the code:这里的代码:
export const PageSettings = (props) => {
const {
table,
listviewFields,
t,
tableCrud,
updatePageSettingsFields,
templates,
visibleFields,
visibleFieldsToggle,
} = props;
let aFields = [];
let aFieldsForSortable = [];
for (const [keyName, fieldSet] of Object.entries(listviewFields)) {
const listViewField = table.listview.fields[keyName];
let fieldSource;
if (listViewField.virtual) {
// virtual don't throw error, must have always label
fieldSource = listViewField;
} else {
fieldSource = table.fields[keyName];
}
const field = table.fields[keyName];
const { aColHeaderToAdd, titleFieldFull, printCell } = getHeaderToAdd(
listViewField,
keyName,
fieldSource,
table,
props,
t,
templates,
tableCrud,
fieldSet,
listviewFields
);
if (printCell) {
aFieldsForSortable.push({ id: keyName, name: titleFieldFull });
aFields.push(
<div
key={keyName}
style={{
fontSize: "12px",
minWidth: "90px",
maxWidtht: "150px",
bgColor:
listviewFields && listviewFields[keyName].invisible === true
? "black"
: "green",
}}
>
<input
type="checkbox"
name={keyName}
style={{}}
checked={
!listviewFields[keyName].invisible ||
listviewFields[keyName].invisible === false
? true
: false
}
onChange={updatePageSettingsFields}
/>
<label htmlFor={keyName}>{titleFieldFull}</label>
</div>
);
}
}
const [stateList, setStateList] = useState([aFieldsForSortable]);
return (
<div
style={{
display: "flex",
flexDirection: "row",
alignItems: "center",
color: "#FFFFFF",
paddingTop: "20px",
width: "100%",
backgroundColor: visibleFields ? "#555555" : null,
}}
>
<a onClick={visibleFieldsToggle}>
<ShowIcon icon="eyecheck" color="#5f97c1" />
</a>
<ReactSortable list={stateList} setList={setStateList}>
{state.map((item) => (
<div key={item.id}>{item.name}</div>
))}
</ReactSortable>
{visibleFields && aFields}
</div>
);
};
const getHeaderToAdd = (
listViewField,
keyName,
fieldSource,
table,
props,
t,
templates,
tableCrud,
fieldSet,
listviewFields
) => {
let colsHeader = [];
let printCell = true;
// Logic Twin TT103
let titleField;
let titleFieldFull;
// fieldSource can be not exist, by example , virtual field: customers.listview.addresses2
if (
fieldSource &&
fieldSource.fieldDisplayedOptions &&
fieldSource.fieldDisplayedOptions.separatorsubfield === "col"
) {
/*
not call main field, but the subfields to get label
*/
for (const [nameSubField, objField] of Object.entries(
fieldSource.fieldDisplayedOptions.subfields
)) {
titleField = resolveListLabel(table.related[keyName].table, nameSubField); // look for related table
titleFieldFull =
titleFieldFull + (titleFieldFull ? " " : "") + titleField;
colsHeader.push(
<div className="cell" key={nameSubField + keyName}>
{t(titleField)}
</div>
);
}
} else {
if (listViewField.module) {
if (
!resolvePathObj(
props,
"myState.app.appSettings.modules." + listViewField.module,
true
)
) {
//if (keyName === 'dateaccounting') console.log('module not compat', props);
printCell = false;
}
}
if (listViewField.templates) {
if (
!intersection(
listViewField.templates,
templates,
props.tableCrud,
keyName
)
) {
//if (keyName === 'dateaccounting') console.log('no template');
printCell = false;
}
}
}
/*if (keyName === 'dateaccounting') {
console.log('module, propstemplates, templates', listViewField.module, templates, listViewField.templates);
}*/
if (printCell) {
titleFieldFull = resolveListLabel(tableCrud, keyName);
// try find short word, if not exist then get normal word
let title = t(titleFieldFull + "_short");
if (title === titleFieldFull + "_short") title = t(titleFieldFull);
titleFieldFull = title;
colsHeader.push(
<div className="cell" key={keyName}>
{titleFieldFull}
</div>
);
}
return { titleFieldFull, printCell, colsHeader };
};
thanks谢谢
You're passing the argument aFieldsForSortable
which is initialized as []
and then conditionally (inside the if statement), you're writing information for that value.您正在传递参数
aFieldsForSortable
,该参数被初始化为[]
,然后有条件地(在 if 语句中),您正在为该值编写信息。
I'd suggest starting the use state as empty and in case you're changing it, call the setStateList
method.我建议开始使用 state 为空,如果您要更改它,请调用
setStateList
方法。 For example,例如,
const [stateList, setStateList] = useState([]);
....
if (printCell) {
const aFieldsForSortable = stateList;
aFieldsForSortable.push({ id: keyName, name: titleFieldFull });
setStateList(aFieldsForSortable);
You are breaking the Rules of Hooks .你违反了钩子规则。
Rules of Hooks say:钩子规则说:
Only Call Hooks at the Top Level
仅在顶层调用 Hooks
Don't call Hooks inside loops, conditions, or nested functions不要在循环、条件或嵌套函数中调用 Hooks
The useState()
call should be at the top of your function. useState()
调用应该在 function 的顶部。 If your initial state is based on a complex calculation, then you should do that calculation inside useEffect()
(setting the value using setStateList()
), otherwise the complex calculation will be re-run every time your Component is re-rendered.如果您的初始 state 是基于复杂计算,那么您应该在
useEffect()
中进行该计算(使用setStateList()
设置值),否则每次重新渲染组件时都会重新运行复杂计算。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.