Home > Software design >  expo | only changes on state while call arrow-function?
expo | only changes on state while call arrow-function?

Time:01-11

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.

CodePudding user response:

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.

CodePudding user response:

The solution from @ghybs worked. I appreciate your work

  • Related