Search code examples
reactjsuse-effect

React useEffect missing dependencies


I'm getting a warning because my useEffect is missing dependencies, but I do not want to add these dependencies because will refresh the page every time I change the input value of these dependencies field.

I have two state data for my start and end date:

const [ startDate, setStartDate ] = useState(moment().subtract(3, 'month').format('YYYY-MM-DD'));
const [ endDate, setEndDate ] = useState(moment().format('YYYY-MM-DD'));

As default, I load the data I'm my useEffect based on the date range:

useEffect(() => {
    async function fetchData() {
        setDataArr(await myAPI.get({
            propertyID,
            userID,
            startDate,
            endDate,
        }));
    }
    fetchData();
}, [propertyID, userID]);

Then, I use them in my form. The goal is to research the data from the database based on the date range selected.

<Form inline>
    <FormGroup className="mb-10 mr-sm-10 mb-sm-0" inline>
        <Label for="startDate" className="mr-sm-10">Start Date:</Label>
        <DatePicker name="startDate" id="startDate" style={{maxWidth: '110px'}}
            value={startDate} onChange={(e) => setStartDate(e ? moment(e).format('YYYY-MM-DD') : '')}
        />
    </FormGroup>
    <FormGroup className="mb-10 mr-sm-10 mb-sm-0" inline>
        <Label for="endDate" className="mr-sm-10">End Date:</Label>
        <DatePicker name="endDate" id="endDate" style={{maxWidth: '110px'}}
            value={endDate} onChange={(e) => setEndDate(e ? moment(e).format('YYYY-MM-DD') : '')}
        />
    </FormGroup>
    <Button className="btn btn-primary" onClick={search}>Update</Button>
</Form>

I'm getting the warning saying that the startDate and endDate are missing in useEffect dependency array, but if I add them, the component reload every time I change one of the date inputs.


Solution

  • I would probably do:

    const [ startDate, setStartDate ] = useState(moment().subtract(3, 'month').format('YYYY-MM-DD'));
    const [ endDate, setEndDate ] = useState(moment().format('YYYY-MM-DD'));
    const [ dateRange, setDateRange ] = useState({startDate, endDate});
    
    <Button
        className="btn btn-primary"
        onClick={() => {
            setDateRange({
                startDate,
                endDate,
            })
        }}
    >
        Update
    </Button>
    
    useEffect(() => {
        async function fetchData() {
            setDataArr(await myAPI.get({
                propertyID,
                userID,
                ...dateRange
            }));
        }
        fetchData();
    }, [propertyID, userID, dateRange]);
    

    And now, you can set startDate and endDate without triggering the update, but it will update when they click search (since that will trigger fetchData when it updates dateRange.