I decided to learn React during the winter holidays and decided that I would like to consume an API designed to create and list comments.
By following the React documentation, I achieved to create comments and get them via an API call using axios and render those on child components. However, I would like to re-render the ListComments component whenever I create a new comment.
I observed from the documentation that a possible solution would be using the useCallback hook when adding a comment and sending a "signal" to the ListComments component via props, but I have not being successful due to my lack of understanding.
Please refer to the following code:
Parent component
function ExercisePage() {
//Load task
const [task, setTask] = useState([]);
//Get task
const loadTask = async () => {
const response = await axios.get("http://localhost:8080/tasks/1");
setTask(response.data)
}
//On function load, fetch data
useEffect(
() => {
console.log("Loading task")
loadTask();
}, [])
return (
<div align="center">
<a href="/home">Home</a>
<h2>{task.taskName}</h2>
<br></br>
<img
src="http://clipart-library.com/data_images/6103.png"
alt="test image"/>
<h2>Detalles del ejercicio</h2>
<p>
{task.details}
</p>
<br></br>
<button>Completado?</button>
<br></br>
<AddComment/>
<br></br>
<ListComments/>
</div>
)
}
export default ExercisePage;
Child component for creating comments
class AddComment extends Component {
constructor(props) {
super(props);
this.state = {
content: '',
creationDate: ''
}
//Bind functions
this.handleInputChange = this.handleInputChange.bind(this)
this.onSubmit = this.onSubmit.bind(this)
}
handleInputChange(event) {
const target = event.target;
const value = target.value
const name = target.name
this.setState({
[name]: value //Dynamically allocate to data <- value
})
}
//Handle the click event from a button/input (onClick)
onSubmit = async (event) => {
event.preventDefault();
console.log("Click")
const date = new Date();
await axios.post('http://localhost:8080/task/'+1+'/comment' ,
{
'comment':
{
'content': this.state.content,
'creationDate': date,
},
'username': 'user1',
'taskId': 1
}).then(res => {
console.log('sending to proooood')
console.log(res.data)
}).catch(err => {
console.log("ERROR " + err.message)
})}
render() {
return (
<div>
<h2>Deja aquĆ tu comentario</h2>
<form
onSubmit={(event) => this.onSubmit(event)}>
<input
id='content-input'
name='content'
placeholder=''
type='text'
onChange={this.handleInputChange}
/>
<br></br>
<button>Comenta</button>
</form>
</div>
)
}
}
export default AddComment;
Child component for reading comments
function ListComments(props) {
const [comments, setComments] = useState([])
const loadComments = async () => {
const result = await axios.get('http://localhost:8080/task/'+1+'/comments');
setComments(result.data);
console.log(result.data)
}
useEffect(() => {
console.log("Populating comments")
loadComments()
}, [])
return (
<div>
<h2>Comentarios</h2>
<ul>
{comments.map((comment,_) => (
<li>{comment.content} || {comment.user.username} || {comment.user.email}</li>
))}
</ul>
</div>
)
}
export default ListComments;
If you have a better suggestion on how could I approach the consumption of the API, please do so. I am open to learn new strategies and best practices to improve.
My main objective with this question is to achieve the intention of refreshing a component when new data is added.