0

Let's say I have a form with some user input fields and a submit button in the header that dispatches a couple of actions when pressed. I use a function called calculate, which takes a user input stored in number and updates a state variable result, which I would like to pass to submitFunction after pressing a submit header button. I am trying to achieve this with useEffect, but for some reason result is not being updated in time.

For example, if I enter 99 in the text input field, result is sent to the submitHandler as 90 instead of 990, i.e. one of the digits from the text input is being left off. Can someone tell me how to modify useEffect or my function calls so that number will be updated in time and the correct value of result is passed to submitHandler?

const ExampleScreen = props => {
    const dispatch = useDispatch();

    const [number, setNumber] = useState(0);
    const [result, setResult] = useState(0);

    const calculate = (n) => {
        setResult(n * 10);
    };

    useEffect(() => {
        calculate(number); // something not working here!
    })

    const submitHandler = useCallback(() => {
        dispatch(updateList(result));
        dispatch(updateTotal(result));
    }, [dispatch, result]);
    
    useEffect(() => {
        props.navigation.setParams({submit: submitHandler});
    }, [submitHandler]);

    return (
        <View>
            <TextInput
                keyboardType='numeric'
                value={number}
                onChangeText={(val) => setNumber(val)}
            />
        </View>
    );
};

ExampleScreen.navigationOptions = navData => {
    const submitFunction = navData.navigation.getParam('submit');
    return {
        headerRight: () => <HeaderButtons>
            <Item 
                title='Submit'
                iconName='md-checkmark'
                onPress={submitFunction}
            />
        </HeaderButtons>
    }
};
blakebullwinkel
  • 305
  • 1
  • 5
  • 15

2 Answers2

1

Restrict the update of result only for change in number value not for every render (if you don't pass second argument to useEffect it updates on every render)

useEffect(() => {
  calculate(number); // something not working here!
}, [number]) // Add number as hook dependency

Or

If you are not using calculate function anywhere else

useEffect(() => {
  setResult(number * 10);
}, [number])

Prathap Reddy
  • 1,688
  • 2
  • 6
  • 18
0

This is because when entering 99, actually there are 2 onChangeText events, the first 9 you entered, you will get 90 as the result from submitHandler, and 990 for the second 9.

I think you may need a debounce function for the input component.

Eric
  • 1,279
  • 1
  • 11
  • 8