在Redux Toolkit中分发一个动作太慢。

huangapple go评论59阅读模式
英文:

Dispatching an action in redux toolkit too slow

问题

以下是您要翻译的内容:

"I am creating a checklist which can have nested items too (same as in trello). After creating a checklist and adding items, though it works fine, but when i try to toggle any item (i can mark it as completed or not completed), I am dispatching an action at that time to update the global state, but it is too slow. It freezes the whole UI.

Here is the relevant code;

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;
},

So here, i am simply accessing the nested item and updating the itemTitle or status accordingly. When changing the itemStatus (toggling the checkbox), it freezes the whole UI and is too slow to update, though it works but is too slow.

One thing which i can think can solve the problem is if we have async actions. So is there any way to dispatch actions asyncronously (this is a secondary question).

EDIT:

This is a rough structure of the components;

My main checklist;

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();

...

Then the nested component;

const CheckItem: FC<CheckItemProps> = ({citem, index, checklistId}) => {
const [value, setValue] = useState(citem?.itemTitle);
const [checked, setChecked] = useState(citem?.itemStatus);

const dispatch = useDispatch();

...

EDIT Found that, it is bacause of too many re-renders. Fixing that now. If anyone can see the issues in the above code which can be causing too many re-renders, please comment down.
Thanks!"

请注意,我已经删除了您的请求以进行翻译,只提供了要翻译的内容。

英文:

I am creating a checklist which can have nested items too (same as in trello). After creating a checklist and adding items, though it works fine, but when i try to toggle any item (i can mark it as completed or not completed), I am dispatching an action at that time to update the global state, but it is too slow. It freezes the whole UI.

Here is the relevant code;

 dispatch(
        updatecarditem({
          checklistId,
          itemId: index,
          itemStatus: checked,
        }),
      );

 updatecarditem: (state: any, {payload}) =&gt; {
      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;
    },

So here, i am simply accessing the nested item and updating the itemTitle or status accordingly. When changing the itemStatus (toggling the checkbox), it freezes the whole UI and is too slow to update, though it works but is too slow.

One thing which i can think can solve the problem is if we have async actions. So is there any way to dispatch actions asyncronously (this is a secondary question).

EDIT:

This is a rough structure of the components;

My main checklist;

export const CheckListItem: FC&lt;CheckListItemProps&gt; = ({item, index}) =&gt; {
  const card = useSelector&lt;any, any&gt;(cardDetails);

  const [value, setValue] = useState(item?.checklistTitle);
  const [newItem, setNewItem] = useState(&#39;&#39;);

  const dispatch = useDispatch();

  useEffect(() =&gt; {
    setValue(item?.checklistTitle);
  }, [item?.checklistTitle]);

  const toggleVisible = () =&gt; {
    setVisible((prev) =&gt; !prev);
  };

  const addCheckistItem = useCallback(() =&gt; {
    if (!newItem.length) {
      return;
    }
    const newCItem = {itemTitle: newItem, itemStatus: false};

    updateChecklist([...item?.checklistItem, newCItem]);
    setNewItem(&#39;&#39;);
  }, [newItem, item?.checklistItem]);

  const updateChecklist = useCallback(
    (clitem = item?.checklistItem) =&gt; {
      if (value.length &lt; 3) {
        showToast(
          &#39;error&#39;,
          &#39;Checklist name should contain atleast 3 characters&#39;,
        );
        return;
      }
      let newls = [...card?.checklist];
      newls[index].checklistTitle = value;
      newls[index].checklistItem = clitem;

      dispatch(
        updatecard({
          checklist: newls,
        }),
      );
    },
    [value, card?.checklist],
  );

  return (
      &lt;VStack style={styles.cardinfoviews}&gt;
       
          &lt;CustomInput
            onSubmit={updateChecklist}
            value={value}
            setValue={setValue}
          /&gt;
     
          &lt;VStack style={styles.cardinfoviews}&gt;
            {item?.checklistItem?.map((citem: any, itemindex: number) =&gt; (
              &lt;CheckItem // THIS IS THE NESTED COMPONENT
                key={itemindex}
                citem={citem}
                index={itemindex}
                checklistId={index}
              /&gt;
            ))}

            &lt;Input
              onSubmitEditing={addCheckistItem}
              value={newItem}
              onChangeText={setNewItem}
              maxLength={40}
              variant=&quot;underlined&quot;
              placeholder=&quot;Add item...&quot;
            /&gt;
          &lt;/VStack&gt;
        )
      &lt;/VStack&gt;
  );
};

Then the nested component;

const CheckItem: FC&lt;CheckItemProps&gt; = ({citem, index, checklistId}) =&gt; {
  const [value, setValue] = useState(citem?.itemTitle);
  const [checked, setChecked] = useState(citem?.itemStatus);

  const dispatch = useDispatch();

  useEffect(() =&gt; {
    setValue(citem?.itemTitle);
  }, [citem?.itemTitle]);

  useEffect(() =&gt; {
    setChecked(citem?.itemStatus);
  }, [citem?.itemStatus]);

  const updatecheckItem = useCallback(
    (checked = citem?.itemStatus) =&gt; {
      setChecked(checked);
      dispatch(
        updatecarditem({
          checklistId,
          itemId: index,
          itemStatus: checked,
        }),
      );
    },
    [checklistId, index],
  );

  const updateItemName = useCallback(() =&gt; {
    if (value.length &lt; 3) {
      showToast(&#39;error&#39;, &#39;Item name should contain atleast 3 characters&#39;);
      return;
    }

    dispatch(
      updatecarditem({
        checklistId,
        itemId: index,
        itemTitle: value,
      }),
    );
  }, [value, index, checklistId]);


  return (
      &lt;Checkbox
        value={citem?.itemTitle}
        isChecked={checked}
        onChange={updatecheckItem}&gt;
          &lt;Input
            w=&quot;85%&quot;
            onSubmitEditing={updateItemName}
            variant=&quot;unstyled&quot;
            value={value}
            onChangeText={setValue}
            multiline
            numberOfLines={1}
            blurOnSubmit
          /&gt;
      &lt;/Checkbox&gt;
  );
};

EDIT Found that, it is bacause of too many re-renders. Fixing that now. If anyone can see the issues in the above code which can be causing too many re-renders, please comment down.
Thanks!

答案1

得分: 0

这个问题与操作的派发无关,而与我从存储中访问数据的方式有关(感谢 @phry),我选择了太多的状态,导致不必要的重新渲染,因为数据正在从多个子组件中更改。已修复重新渲染,但子组件仍需要一些优化。

英文:

This issue was not related to actions being dispatched but the way i was accessing the data from store (thanks to @phry), I was selecting too much of the state which caused unnecessary re-renders as the data was being changed from multiple child components. Fixed the re-rendering but still some optimisation needed in the child components.

huangapple
  • 本文由 发表于 2023年6月13日 12:19:37
  • 转载请务必保留本文链接:https://go.coder-hub.com/76461669.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定