I was using copilot for while and it was really helpful to speed up the development. But wanted to give a try how ChatGPT compares with copilot as assistance. So I choose a simple use case of generating code for displaying list addresses and editing them in screen.
Here is the first prompt I gave to ChatGPT and code generated by ChatGPT
Create a react js code to edit list of address and delete using service calls
first chat prompt
The initial version was already good, but I don’t like to use table to present or edit address data. So I gave another prompt and ChatGPT revised the code based on that.
import React, { useState, useEffect } from 'react';
import axios from 'axios';
const AddressList = () => {
const [addresses, setAddresses] = useState([]);
const [editingId, setEditingId] = useState(null);
useEffect(() => {
axios.get('/api/addresses')
.then(res => setAddresses(res.data))
.catch(err => console.log(err));
}, []);
const handleEdit = id => {
setEditingId(id);
};
const handleDelete = id => {
axios.delete(`/api/addresses/${id}`)
.then(() => {
setAddresses(addresses.filter(address => address.id !== id));
})
.catch(err => console.log(err));
};
const handleUpdate = (id, updatedAddress) => {
axios.put(`/api/addresses/${id}`, updatedAddress)
.then(() => {
setAddresses(addresses.map(address => {
if (address.id === id) {
return updatedAddress;
} else {
return address;
}
}));
setEditingId(null);
})
.catch(err => console.log(err));
};
return (
<div>
<h1>Address List</h1>
{addresses.map(address => {
if (editingId === address.id) {
return (
<div key={address.id}>
<input
type="text"
value={address.name}
onChange={e => {
address.name = e.target.value;
}}
/>
<input
type="text"
value={address.address}
onChange={e => {
address.address = e.target.value;
}}
/>
<button onClick={() => handleUpdate(address.id, address)}>Save</button>
<button onClick={() => setEditingId(null)}>Cancel</button>
</div>
);
} else {
return (
<div key={address.id}>
<div>Name: {address.name}</div>
<div>Address: {address.address}</div>
<button onClick={() => handleEdit(address.id)}>Edit</button>
<button onClick={() => handleDelete(address.id)}>Delete</button>
</div>
);
}
})}
</div>
);
};
As you can see the table has been replaced with divs, and if you can see carefully you will notice a bad practice. Yes the data is mutated directly in state. This should be avoided. So here is my next prompt to correct it.
A simple prompt “without mutating the state” makes ChatGPT to attempt to rewrite the code as we intended. Below is the third revision of the code.
import React, { useState, useEffect } from 'react';
import axios from 'axios';
const AddressList = () => {
const [addresses, setAddresses] = useState([]);
const [editingId, setEditingId] = useState(null);
useEffect(() => {
axios.get('/api/addresses')
.then(res => setAddresses(res.data))
.catch(err => console.log(err));
}, []);
const handleEdit = id => {
setEditingId(id);
};
const handleDelete = id => {
axios.delete(`/api/addresses/${id}`)
.then(() => {
setAddresses(prevAddresses => prevAddresses.filter(address => address.id !== id));
})
.catch(err => console.log(err));
};
const handleUpdate = (id, updatedAddress) => {
axios.put(`/api/addresses/${id}`, updatedAddress)
.then(() => {
setAddresses(prevAddresses =>
prevAddresses.map(address => {
if (address.id === id) {
return updatedAddress;
} else {
return address;
}
})
);
setEditingId(null);
})
.catch(err => console.log(err));
};
return (
<div>
<h1>Address List</h1>
{addresses.map(address => {
if (editingId === address.id) {
return (
<div key={address.id}>
<input
type="text"
value={address.name}
onChange={e => {
address.name = e.target.value;
}}
/>
<input
type="text"
value={address.address}
onChange={e => {
address.address = e.target.value;
}}
/>
<button onClick={() => handleUpdate(address.id, address)}>Save</button>
<button onClick={() => setEditingId(null)}>Cancel</button>
</div>
);
} else {
return (
<div key={address.id}>
<div>Name: {address.name}</div>
<div>Address: {address.address}</div>
<button onClick={() => handleEdit(address.id)}>Edit</button>
<button onClick={() => handleDelete(address.id)}>Delete</button>
</div>
);
}
})}
</div>
It is nice ChatGPT gives good explanation and starts to rewrite. But the goal is not fully accomplished as you can see within the map loop as the address is updated directly.
Conclusion
ChatGPT can help to drastically speed up your development, still you need to understand the generated code so that you are in control and make sure to use only the code which adhere to the best practices.
Having ChatGPT is using a powerful car but it is programmer the as driver has to make decision to drive it correctly and not to crash. 🙂 Modern cars comes with many safety features and similar way ChatGPT also will improve over the time in terms of safety and providing more satisfying code. But it will be always the user’s responsibility to use it correctly.