在 axios 中使用时,react 钩子抛出错误的 useEffect

时间:2021-05-11 16:01:32

标签: reactjs react-hooks

如何解决以下问题?:

我正在使用 react 钩子来处理 Primereact 数据表。当我尝试在类似于 sandbox example here 的 axios 调用(注释掉下面代码中的部分代码)中使用 useEffect 时,我不断收到以下错误:

Error: Invalid hook call. Hooks can only be called inside of the body of a function component. This could happen for one of the following reasons:
1. You might have mismatching versions of React and the renderer (such as React DOM)
2. You might be breaking the Rules of Hooks
3. You might have more than one copy of React in the same app

这很可能是因为上面的 #2。我应该尝试在 useEffect 内部调用 api 而不是在这里使用 axios 吗?

但是,当我在 axios 外部使用 useEffect 时,它的工作方式很好,但我希望它在 axios 内部,以便我可以使用响应来显示数据。

import React, { useReducer, useEffect } from 'react';
import axios from 'axios'
import { Dropdown } from 'primereact/dropdown';
import { DataTable } from 'primereact/datatable';
import {Column} from "primereact/column";
import testdata from "./test-data.json";


const RequestForm = (props) => {
    
    console.log(props.companyRequest.requestId);
    let editedcompanyRequestId = props.companyRequest.requestId;

   
    // START: Datatable related code with React Hooks

    const init = (initialState) => initialState;

    const reducer = (state, action) => {
            switch (action.type) {
                case "dataLoaded":
                return { ...state, results: action.payload, loading: false };
                default:
                throw new Error();
            }
    };

    const initialState = {
        results: [],
        loading: true
      };
      const [state, dispatch] = useReducer(reducer, initialState, init);
      const { results, loading } = state;

      var receivedResponse;
      axios
         .get("api/companyLookup?requestId="+editedcompanyRequestId)
         .then(response => {
              console.log('Printing Response.data ....')
              console.log(response.data);
              receivedResponse = response.data;
              console.log("Received Response below inside axios")
              console.log(receivedResponse);
            //   useEffect(() => {
            //     if (loading) {
            //       dispatch({
            //         type: "dataLoaded",
            //         payload: receivedResponse.map((row) => {
            //           const [vin, year, brand, color] = row.split(",");
            //           return {
            //             vin,
            //             year,
            //             brand,
            //             color
            //           };
            //         }, [])
            //       });
            //     }
            //   }, [loading]);
        
         }).catch(err => console.log(err));  

         console.log("Received Response below");
         console.log(receivedResponse);

      useEffect(() => {
        if (loading) {
          dispatch({
            type: "dataLoaded",
            payload: testdata.map((row) => {
              const [vin, year, brand, color] = row.split(",");
              return {
                vin,
                year,
                brand,
                color
              };
            }, [])
          });
        }
      }, [loading]);


     // END: Datatable related code with React Hooks


    
    
    



    return (
        <div>
            
            <div id="formDiv">
                <Growl ref={growl}/>
                <Form className="form-column-3">
                    <div className="form-field field-full-width">
                        <DataTable value={results}>
                           <Column field="vin" header="Company ID" />
                           <Column field="year" header="Company File Name" />
                           <Column field="brand" header="Company Description" />
                           <Column field="color" header="Owner ID" />
                        </DataTable>
                    </div>  
                  
                    <div className="btn-group-right">
                        <Button size="large" variant="contained" color="primary"
                                type="submit">Submit</Button>
                        <Button size="large" variant="contained" color="primary" onClick={handleReset}
                                style={{marginLeft: '5px'}} type="button">Reset</Button>
                        <Button size="large" variant="contained" color="primary" onClick={props.onCancel}
                                style={{marginLeft: '5px'}} type="button">Cancel</Button>
                    </div>
                </Form>
            </div>
        </div>
    )

};


export const CompanyRequestEnhancedFormEdw = withFormik({


     mapPropsToValues: props => {

        // console.log("Props TESTING Inside const companyRequestEnhancedFormEdw = withFormik({ ****************************************************************");
        // console.log(props);
    

        return {
           

            //some code here
        }
    },

    validationSchema:validationSchema,
    handleSubmit(values, {props, resetForm, setErrors, setSubmitting}) {
       //some code
    },
    setFieldValue(field, value, shouldVal) {
        console.log('In setFieldValue')
    },

    displayName: 'Company Request Form',
})(RequestForm)

1 个答案:

答案 0 :(得分:1)

如果要获取数据,请在 useEffect() 钩子内进行。

const [data, setData] = useState();

useEffect(() => {
  axios
    .get("url")
    .then((res) => {
      setData(res.data);
    })
    .catch((error) => {
      console.log(error);
    });
}, []);

获取数据时,状态值会更新,从而导致页面重新呈现。

示例Sandbox here

相关问题