0

im new to learning react and im reached an issue that no amount of debugging could solve, for some reason even though im loading the object from the API successfully its not willing to update the activity state in the useEffect() is there smth wrong with using this object as a state or smth? cuz i couldnt find the issue at all. and even the fields in the component arent filling with the default acitivty values and what I get when logging the activity object is whats written after the code, which is basically the object with empty parameters, but added is some sort of prototype object

export default observer(function ActivityForm() {
    const { activityStore } = useStore();
    const { loadActivity, loadingInitial, createActivity, updateActivity, loading } = activityStore;

    const { id } = useParams();
    const [activity, setActivity] = useState({
        id: '',
        title: '',
        description: '',
        venue: '',
        category: '',
        city: '',
        date: '',
    });

    useEffect(() => {
        if (id) {
            loadActivity(id).then(act => setActivity(act!));
            
        }
    }, [id, loadActivity]);

    function handleSubmit() {
        activity.id ? updateActivity(activity) : createActivity(activity);
    }

    function handleInputChange(event: ChangeEvent<HTMLInputElement>) {
        const { name, value } = event.target;
        setActivity({ ...activity, [name]: value });
    }

    function handleDateInputChange(val: string | null) {
        if (val == null) return;
        var d = moment(new Date(val.toString())).format("YYYY-MM-DDTHH:mm:ss");
        setActivity({ ...activity, ['date']: d?.toString() ?? "" });
    }


    if (loadingInitial) return <LoadingComponent content="loading activity..." />
    return (
        <Box
            component="form"
            sx={{ '& > :not(style)': { m: 1, width: '30ch' }, }}
            noValidate
            autoComplete="off"
            onSubmit={handleSubmit}
        >
            <TextField id="1" name="title" label="Title" variant="outlined" defaultValue={activity ? activity.title : ""} onChange={handleInputChange} />
            <TextField id="2" name="description" label="Description" variant="outlined" defaultValue={activity ? activity.description : ""} onChange={handleInputChange} />
            <TextField id="3" name="category" label="Category" variant="outlined" defaultValue={activity ? activity.category : ""} onChange={handleInputChange} />
            <LocalizationProvider dateAdapter={AdapterDateFns}>
                <DatePicker
                    label="Date"
                    value={activity ? activity.date : ""}
                    onChange={handleDateInputChange}
                    renderInput={(params) => <TextField {...params} />}
                />
            </LocalizationProvider>
            <TextField id="5" name="city" label="City" variant="outlined" defaultValue={activity ? activity.city : ""} onChange={handleInputChange} />
            <TextField id="6" name="venue" label="Venue" variant="outlined" defaultValue={activity ? activity.venue : ""} onChange={handleInputChange} />

            <Button variant="contained" onClick={handleSubmit}>{loading ? <LoadingComponent /> : "Submit"}</Button>
            <Button >Cancel</Button>
        </Box>)
})

when logging activity object:

{id: '', title: '', description: '', venue: '', category: '', …}
category: ""
city: ""
date: ""
description: ""
id: ""
title: ""
venue: ""
[[Prototype]]: Object
constructor: ƒ Object()
hasOwnProperty: ƒ hasOwnProperty()
isPrototypeOf: ƒ isPrototypeOf()
propertyIsEnumerable: ƒ propertyIsEnumerable()
toLocaleString: ƒ toLocaleString()
toString: ƒ toString()
valueOf: ƒ valueOf()
__defineGetter__: ƒ __defineGetter__()
__defineSetter__: ƒ __defineSetter__()
__lookupGetter__: ƒ __lookupGetter__()
__lookupSetter__: ƒ __lookupSetter__()
__proto__: (...)
get __proto__: ƒ __proto__()
set __proto__: ƒ __proto__()

1 Answers1

0

According to the docs:

State Updates May Be Asynchronous

React may batch multiple setState() calls into a single update for performance.

Because this.props and this.state may be updated asynchronously, you should not rely on their values for calculating the next state.

Reference: https://reactjs.org/docs/state-and-lifecycle.html#state-updates-may-be-asynchronous

Luis Montoya
  • 3,117
  • 1
  • 17
  • 26