1

i have a problem with following function;

const handleSave = (task, description, priorityState, taskID) => {
  changeLabel(task, taskID);
  changeDescription(description, taskID);
  changePriority(priorityState, taskID);
  navigation.goBack();
};

the problem is thats only change the last used function:

if i'll change the Label and the Description its only save the Description for example. < i call the function while clicking a Button (TouchableOpacity)

<Button
  title={language.edit.save}
  color={theme.secondary}
  onPress={() => {
    handleSave(task, description, priorityState, taskID);
  }}
/>

any advise?

what did i try? delay the functions:

function sleep(ms) {
  return new Promise(resolve => setTimeout(resolve, ms));
}

const handleSave = (task, description, priorityState, taskID) => {
  changeLabel(task, taskID);
  sleep(10); 
  changeDescription(description, taskID);
  sleep(10); ...
};

i would like to thank any kind of help <3

full code here.

lxgg
  • 11
  • 2
  • As a side note: `sleep(10)` returns a Promise. If you don't `await` it, it won't wait for it to finish – A_A Jan 09 '23 at 18:09
  • Did you try to put it all the state that changes together in a single state object (e.g. only one `useState()` instead of three)? I remember this helped me some time ago, but don't know why – A_A Jan 09 '23 at 18:10
  • I assume `changeLabel`/Description/Priority are custom functions, and there is a high probability the issue is caused by their inner working, so without their code, it is almost impossible to provide relevant help. Please make sure to share a [mcve]. – ghybs Jan 09 '23 at 18:19
  • @ghybs i added a github link. context/task/Index.js there are all the functions – lxgg Jan 09 '23 at 18:38
  • @A_A thx for the Information i'll try it as soon i'm back from School tomorrow. (eu time | 16:00uhr/4:00pm) – lxgg Jan 09 '23 at 18:44
  • Next time make sure to provide a _minimal_ code. See [How to ask](https://stackoverflow.com/help/asking). – ghybs Jan 09 '23 at 19:18
  • @ghybs i cant rn im not on my pc I'll do it tomorrow.. i'm dont ask many question here. rn on my phone so i just added github link. on my other comment i said i'll do it tommorrow after scholl – lxgg Jan 09 '23 at 19:29

2 Answers2

0

Your 3 custom functions changeLabel, changeDescription and changePriority all try to update the same tasks state:

Repo source

const [tasks, setTasks] = useState([]);

const changePriority = (color, taskID) => {
  const task = tasks.map(/* etc. */);
  setTasks(task);
};

const changeDescription = (description, taskID) => {
  const task = tasks.map(/* etc. */);
  setTasks(task);
};

const changeLabel = (value, taskID) => {
  const task = tasks.map((/* etc. */);
  setTasks(task);
};

When you successively call these functions, each one reads the current tasks state, which has not been updated yet by the previous call to setTasks SetStateAction. See also The useState set method is not reflecting a change immediately

You can easily solve this by using the functional update form of the SetStateAction:

If the new state is computed using the previous state, you can pass a function to setState. The function will receive the previous value, and return an updated value.

In your case, change your 3 functions to get the previous state as a parameter:

const changePriority = (color, taskID) => {
  setTasks(
    // Use previous tasks received as argument
    // instead of directly tasks which may be
    // an old value.
    (previousTasks) => previousTasks.map(/* etc. */)
  );
};

// Same for the other 2 functions.
ghybs
  • 47,565
  • 6
  • 74
  • 99
0

The solution from @ghybs worked. I appreciate your work Thx

i changed the function from:

const markTask = (taskID) => {
  const task = tasks.map((item) => {
    if (item.id == taskID) {
      return { ...item, completed: true };
    }
    return item;
  });
  setTasks(task);
};

to this:

const changeLabel = (value, taskID) => {
  setTasks((previousTasks) =>
    previousTasks.map((item) => {
      if (item.id == taskID) {
        return { ...item, label: value };
      }
      return item;
    })
  );
};

snack with the issue

lxgg
  • 11
  • 2