0

New to react and working on a project. I have a component which is using a GET request from backend. all seems to work properly apart from when I try to save response data using useState() hook

whenever I try to setCompany with data I get an infinite loop while checking my console log.

without setting Company this does not happen.

I couldn't seem to find the right answer on other post's.

Component: interface GetOneCompanyProps {

    company: CompanyModel;
}

interface RouteParam {
    id: any;
}

interface CompanyById extends RouteComponentProps<RouteParam> { 

}


function GetOneCompany(props: GetOneCompanyProps): JSX.Element {

    const [id, setId] = useState('1');
    const [company, setCompany] = useState([]);
   
    const handleSubmit = (e) => {
        e.preventDefault();  
        console.log(id)
    }

    async function send() {
        
    
        try {
            const response = await axios.get<any>(globals.adminUrls.getOneCompany + id)  

                store.dispatch(oneCompanyAction(response.data) );
                console.log(response);
                const company = response.data;
                setCompany(company);

        } catch (err) {
            notify.error(err);
        }
    }

    useEffect(() => {
       
        send(); 
    });
    return (
        <div className="getOneCompany">
            <h1>hi  </h1>
            <form onSubmit={handleSubmit}>
                <label>Company ID</label>
                <input value={id} onChange={(e) => setId(e.target.value)} type="number"/>
                <input  type="submit"  value="Search "/>
            </form>

            <div>

            </div>

        </div>

    );
}

export default GetOneCompany;

I sure I am doing something wrong but cannot seem to get to it.

Thanks.

Daniel R
  • 7
  • 7

1 Answers1

3

By calling useEffect without dependencies, it'll be called on every single render cycle:

useEffect(() => {   
    send(); 
});

To execute the effect only when the component initially renders, add an empty array as dependencies:

useEffect(() => {   
    send(); 
}, []);

Update As @KausUntwale pointed out, you're using id inside your send() function. To execute send any time id changes, add id to your useEffect dependencies:

useEffect(() => {   
    send(); 
}, [id]);
fjc
  • 5,590
  • 17
  • 36
  • 2
    this is correct, but it looks like they are also using setId further down in the render call, so I would add Id as a dependency instead of the empty array, that way component re-renders when Id changes – Kaus2b Sep 24 '21 at 20:56
  • @KausUntwale that's a great point, I'll edit it into the response. – fjc Sep 24 '21 at 20:56
  • Thanks you @KausUntwale and @fjc. this solved my problem. also. since I am new to this what would be to map `company` since it returns an array? I would like the result to show on my component. – Daniel R Sep 24 '21 at 21:16
  • 1
    i dont understand the question. Can you just write sample of what is in the array and what you need out of it? – Kaus2b Sep 24 '21 at 21:20
  • @KausUntwale it contains information of the company like `name`, `email` , etc .. and a list of `coupons` that the company owns, however, I only need properties like `name` and `email`. I usually do my components as `Class components`. – Daniel R Sep 24 '21 at 21:39
  • https://stackoverflow.com/questions/19590865/from-an-array-of-objects-extract-value-of-a-property-as-array – Kaus2b Sep 24 '21 at 21:44