自定义反应挂钩以获取数据在第二次点击时未提供数据

时间:2019-12-31 06:42:55

标签: javascript reactjs react-hooks

我有一个下面的自定义useEffect钩子,用于从API提取数据。

export const useGetData = (url, body, isNew) => {
const [state, setState] = useState([]);
const [error, setError] = useState({});

useEffect(() => {
    if (isNew) {
        fetch(url, {
            method: 'Post',
            headers: {
                'Content-Type': 'application/json'
            },
            body: JSON.stringify(body)
        }).then(response => response.json())
            .then(apiData => {
                   setState({ apiData });
            }).catch(error =>
                console.error('Error:', error)
            );
        setError(error);
        console.log("Error: " + error);
        return error;
    }
}, []);
return state;
}

现在,在我的组件中,我尝试在发生以下handleInputChanges事件之后使用上述钩子

let dt = {};
const [inputParam, setInputParam] = useState({
    FirstName: 'Tom',
    LastName : 'Harris'
});

const handleInputChanges = (params) =>{
    setInputParam(params);
};

dt = useGetData (url, inputParam, true);

使用上面的代码,我可以点击useGetData自定义钩子,但是钩子没有调用API网址,因此数据dt没有更新。怎么了?请提出。

2 个答案:

答案 0 :(得分:1)

您没有在useEffect内部正确传递第二个参数。

像这样

useEffect(() => {
    if (isNew) {
        fetch(url, {
            method: 'Post',
            headers: {
                'Content-Type': 'application/json'
            },
            body: JSON.stringify(body)
        }).then(response => response.json())
            .then(apiData => {
                   setState({ apiData });
            }).catch(error =>
                console.error('Error:', error)
                setError(error); // Save your error inside the catch block
            );

        // return error; <-- Do not return anything that isn't used for useEffect cleanup! Use return only for cleanup, like unsubscribing API. 
    }
}, [isNew]); <--- This will ensure that everytime isNew changes, it will run the useEffect again. 

但是您可能想将依赖项更改为其他变量,因为isNew是一个布尔值,因此,我认为如果在下一次调用时再次传递true,则它可能不起作用。

您可以将URL用作useEffect的依赖项,这样,在每个新URL上,它将在useEffect内运行调用。

答案 1 :(得分:1)

您正在useEffect的第二个参数中使用空数组,当props更改时,此参数不会更新。这类似于componentDidMount。 您需要要么传递[url,body,isNew]之类的道具,要么根本不传递useEffect中的第二个参数。

export const useGetData = (url, body, isNew) => {
const [state, setState] = useState([]);
const [error, setError] = useState({});

useEffect(() => {
    if (isNew) {
        fetch(url, {
            method: 'Post',
            headers: {
                'Content-Type': 'application/json'
            },
            body: JSON.stringify(body)
        }).then(response => response.json())
            .then(apiData => {
                   setState({ apiData });
            }).catch(error =>
                console.error('Error:', error)
            );
        setError(error);
        console.log("Error: " + error);
        return error;
    }
}, [url, body, isNew]);
return state;
}