我正在创建一个清单,它也可以有嵌套的项目(与Trello相同)。创建检查表并添加项目后,虽然它工作正常,但当我尝试切换任何项目时(我可以将其标记为已完成或未完成),我当时正在调度一个操作来更新全局状态,但它太慢了。它冻结了整个UI。
下面是相关代码;
dispatch(
updatecarditem({
checklistId,
itemId: index,
itemStatus: checked,
}),
);
updatecarditem: (state: any, {payload}) => {
const checklistId = payload.checklistId;
const itemId = payload.itemId;
let item =
state.entities[0]?.checklist?.[checklistId]?.checklistItem?.[itemId];
if (payload.itemTitle != undefined) item.itemTitle = payload.itemTitle;
if (payload.itemStatus != undefined) item.itemStatus = payload.itemStatus;
},
因此,在这里,我只是访问嵌套的项并相应地更新itemTitle或状态。当改变itemStatus(切换复选框)时,它会冻结整个UI,更新太慢,虽然它可以工作,但太慢了。
我认为可以解决这个问题的一件事是,如果我们有异步操作。那么,有没有什么方法可以异步地分派操作(这是一个次要的问题)。
编辑:
这是组件的粗略结构;
我的主要检查表;
export const CheckListItem: FC<CheckListItemProps> = ({item, index}) => {
const card = useSelector<any, any>(cardDetails);
const [value, setValue] = useState(item?.checklistTitle);
const [newItem, setNewItem] = useState('');
const dispatch = useDispatch();
useEffect(() => {
setValue(item?.checklistTitle);
}, [item?.checklistTitle]);
const toggleVisible = () => {
setVisible((prev) => !prev);
};
const addCheckistItem = useCallback(() => {
if (!newItem.length) {
return;
}
const newCItem = {itemTitle: newItem, itemStatus: false};
updateChecklist([...item?.checklistItem, newCItem]);
setNewItem('');
}, [newItem, item?.checklistItem]);
const updateChecklist = useCallback(
(clitem = item?.checklistItem) => {
if (value.length < 3) {
showToast(
'error',
'Checklist name should contain atleast 3 characters',
);
return;
}
let newls = [...card?.checklist];
newls[index].checklistTitle = value;
newls[index].checklistItem = clitem;
dispatch(
updatecard({
checklist: newls,
}),
);
},
[value, card?.checklist],
);
return (
<VStack style={styles.cardinfoviews}>
<CustomInput
onSubmit={updateChecklist}
value={value}
setValue={setValue}
/>
<VStack style={styles.cardinfoviews}>
{item?.checklistItem?.map((citem: any, itemindex: number) => (
<CheckItem // THIS IS THE NESTED COMPONENT
key={itemindex}
citem={citem}
index={itemindex}
checklistId={index}
/>
))}
<Input
onSubmitEditing={addCheckistItem}
value={newItem}
onChangeText={setNewItem}
maxLength={40}
variant="underlined"
placeholder="Add item..."
/>
</VStack>
)
</VStack>
);
};
然后是嵌套组件;
const CheckItem: FC<CheckItemProps> = ({citem, index, checklistId}) => {
const [value, setValue] = useState(citem?.itemTitle);
const [checked, setChecked] = useState(citem?.itemStatus);
const dispatch = useDispatch();
useEffect(() => {
setValue(citem?.itemTitle);
}, [citem?.itemTitle]);
useEffect(() => {
setChecked(citem?.itemStatus);
}, [citem?.itemStatus]);
const updatecheckItem = useCallback(
(checked = citem?.itemStatus) => {
setChecked(checked);
dispatch(
updatecarditem({
checklistId,
itemId: index,
itemStatus: checked,
}),
);
},
[checklistId, index],
);
const updateItemName = useCallback(() => {
if (value.length < 3) {
showToast('error', 'Item name should contain atleast 3 characters');
return;
}
dispatch(
updatecarditem({
checklistId,
itemId: index,
itemTitle: value,
}),
);
}, [value, index, checklistId]);
return (
<Checkbox
value={citem?.itemTitle}
isChecked={checked}
onChange={updatecheckItem}>
<Input
w="85%"
onSubmitEditing={updateItemName}
variant="unstyled"
value={value}
onChangeText={setValue}
multiline
numberOfLines={1}
blurOnSubmit
/>
</Checkbox>
);
};
编辑发现,这是因为太多的重新渲染。现在就修如果任何人都可以看到上述代码中的问题,这可能会导致太多的重新渲染,请评论下来。谢谢!
1条答案
按热度按时间bvuwiixz1#
这个问题与正在调度的操作无关,而是我从store访问数据的方式(感谢@phry),我选择了太多的状态,这导致了不必要的重新渲染,因为数据正在从多个子组件中更改。修复了重新渲染,但仍然需要在子组件中进行一些优化。