after tried to set a simple search in the logs show this:
everything seems very ok and standardized so a couple of searches i still have any idea why this error is happening.
i've tried with fetch and the same result
please, someone can elucidate, why this error is happening?
the code:
import React, { Component } from "react";
import axios from "axios";
import Suggestions from "./suggestions";
class Search extends Component {
constructor(props) {
super(props);
this.state = {
term: "",
error: false,
results: []
};
}
onChange(e) {
this.setState(
{ term: e.target.value },
() => {
axios
.get("/search?q=" + this.state.term)
.then(res => this.setState({ results: res.data }))
.catch(() => this.setState({ error: true }));
}
);
}
render() {
return (
<div id="searchbox">
<div>
<form>
<input
ref={input => {
this.search = input;
}}
value={this.state.term}
onChange={this.onChange.bind(this)}
type="text"
placeholder="Search..."
/>
<button type="submit">
<i className="search icon" />
</button>
<Suggestions results={this.state.results} />
</form>
</div>
</div>
);
}
}
export default Search;
the suggestion
import React from "react";
const Suggestions = props => {
const resultList = props.results.map(r => <li key={r.id}>{r.title}</li>);
return <ul>{resultList}</ul>;
};
export default Suggestions;
response
res.data will give you the entire parsed JSON response, but you want the array that is the value of the posts property instead.
axios
.get("/search?q=" + this.state.term)
.then(res => this.setState({ results: res.data.posts }))
.catch(() => this.setState({ error: true }));
IMO you need use
axios
.get("/search?q=" + this.state.term)
.then(res => this.setState({ results: res.data.posts }))
.catch(() => this.setState({ error: true }));
and not
axios
.get("/search?q=" + this.state.term)
.then(res => this.setState({ results: res.data }))
.catch(() => this.setState({ error: true }));
Related
This is my edit-exercises component given below. So in my exercises component when I am clicking
edit to update my exercises with respect to its id, it has to render to edit-exercise component
but on rendering it gives above mentioned error. This is my component for the reference. In this, in
useEffect I am fetching my exercise with given id from the URL.
import DatePicker from "react-datepicker";
import "react-datepicker/dist/react-datepicker.css";
import axios from "axios";
const EditExercise = (props) => {
const [userDetails, setUserDetails] = useState({
username: "",
description: "",
duration: 0,
date: new Date(),
users: [],
});
useEffect(() => { //This is the getting from backend
axios
.get("http://localhost:5000/exercises/"+props.match.params.id)
.then(res => {
setUserDetails({
username: res.data.username,
description: res.data.description,
duration: res.data.duration,
date: new Date(res.data.date),
})
})
.catch((err) => {
console.log(err);
});
axios
.get("http://localhost:5000/users/")
.then((res) => {
if (res.data.length > 0) {
setUserDetails({
users: res.data.map((user) => user.username),
});
}
})
.catch((err) => {
console.log(err);
});
},[props.match.params.id]);
const changeUsernameHandler = (e) => {
setUserDetails((prevState) => {
return {
...prevState,
username: e.target.value,
};
});
};
const changeDescriptionHandler = (e) => {
setUserDetails((prevState) => {
return {
...prevState,
description: e.target.value,
};
});
};
const changeDurationHandler = (e) => {
setUserDetails((prevState) => {
return {
...prevState,
duration: e.target.value,
};
});
};
const changeDateHandler = (date) => {
setUserDetails((prevState) => {
return {
...prevState,
date: date,
};
});
};
const onSubmitHandler = (e) => { //On submit this code will run
e.preventDefault();
const exercise = {
username: userDetails.username,
description: userDetails.description,
duration: userDetails.duration,
date: userDetails.date,
};
console.log(exercise);
axios
.post("http://localhost:5000/exercises/update/"+props.match.params.id, exercise)
.then((res) => console.log(res.data));
window.location = "/";
};
return (
<div>
<h3>Edit Exercise log</h3>
<form onSubmit={onSubmitHandler}>
<div className="form-group">
<label>Username: </label>
<select
required
className="form-control"
onChange={changeUsernameHandler}
value={userDetails.username}
>
{userDetails.users.map((user) => {
return (
<option key={user} value={user}>
{user}
</option>
);
})}
</select>
</div>
<div className="form-group">
<label>Description: </label>
<input
type="text"
required
className="form-control"
onChange={changeDescriptionHandler}
value={userDetails.description}
/>
</div>
<div className="form-group">
<label>Duration (in minutes): </label>
<input
type="number"
className="form-control"
onChange={changeDurationHandler}
value={userDetails.duration}
/>
</div>
<div className="form-group">
<label>Date: </label>
<div>
<DatePicker
onChange={changeDateHandler}
selected={userDetails.date}
/>
</div>
</div>
<div>
<input
type="submit"
value="Edit Exercise Log"
className="btn btn-primary"
/>
</div>
</form>
</div>
);
};
export default EditExercise;```
>Please suggest what can be done to render the edit-exercise component
Cannot read property 'map' of undefined
This error is thrown because the array you are trying to map doesn't exist. Please check if the array exists before you map the array.
users: res.data ? res.data.map((user) => user.username) : [],
And
{userDetails.users && userDetails.users.map((user) => {
return (
<option key={user} value={user}>
{user}
</option>
);
})}
Since axios.get returns a promise, and setUserDetails is set after the promise is returned, you need to be careful on when useEffect is triggered. Currently useEffect is triggered when props.match.params.id is changed.
There are 2 possible solutions for it:
Either, you can remove props.match.params.id from the useEffect second parameter.
Or you can this section outside the useEffect hook:
axios
.get("http://localhost:5000/users/")
.then((res) => {
if (res.data.length > 0) {
setUserDetails({
users: res.data.map((user) => user.username),
});
}
})
.catch((err) => {
console.log(err);
});
I have two pages on my react app. One page allows you to submit a post, and the second page shows all of the posts. I need to be able to retrieve the data from the state on one page, but I am receiving an error. What am I doing wrong to display this, because I thought I could use props to gather the state from my post page.
My Display Post Page:
import React from 'react';
import './App.css';
export default class Scroll extends React.Component {
render() {
return (
<div className="flex-container">
<div className="post">
{this.props.displayPost(this.props.state.posts)}
</div>
</div>
);
}
}
My post page:
import React from 'react';
import axios from 'axios';
import './App.css';
import { post } from '../../routes/routes';
export default class PersonList extends React.Component {
state = {
title: "",
body: "",
posts: []
};
componentDidMount = () => {
this.getPost();
}
getPost = () => {
axios.get("http://localhost:5000/posts/save")
.then((response) => {
const data = response.data;
this.setState({ posts: data });
console.log("Data has been recieved")
})
.catch(() => {
alert("Error recieving data")
})
}
handleChange = (event) => {
const target = event.target;
const name = target.name;
const value = target.value;
this.setState({
[name]: value
})
};
submit = (event) => {
event.preventDefault();
const payload = {
title: this.state.title,
body: this.state.body,
}
axios({
url: 'http://localhost:5000/posts/save',
method: 'POST',
data: payload,
})
.then(() => {
console.log('Data sent to the server');
})
.catch(() => {
console.log('Internal server error');
});
};
displayPost = (posts) => {
if (!post.length) return null;
return posts.map((post, index) => {
<div key={index}>
<h3 id="post-text">{post.title}</h3>
<p id="post-text">{post.body}</p>
</div>
});
}
render() {
console.log("State ", this.state)
return (
<div className="flex-container-home">
<div className="app">
<form onSubmit={this.submit}>
<input
placeholder="title"
type="text"
name="title"
value={this.state.title}
onChange={this.handleChange}
/>
<textarea placeholder="description"
name="body"
cols="30" rows="10"
value={this.state.body}
onChange={this.handleChange}
>
</textarea>
<button>Submit</button>
</form>
</div>
</div>
)
}
}
Here is working example:
import React from "react";
export default class PersonList extends React.Component {
state = {
title: "",
body: "",
posts: [],
};
componentDidMount = () => {
this.getPost();
};
getPost = () => {
this.setState({ posts: ["post1", "post2", "post3"] });
};
displayPost = (posts) => {
if (!posts || !posts.length) return null;
return posts.map((post, index) => (
<div key={index}>
<p>{post}</p>
</div>
));
};
render() {
return (
<div className="App">
<Scroll displayPost={this.displayPost} posts={this.state.posts} />
</div>
);
}
}
class Scroll extends React.Component {
render() {
return (
<div className="post">
Posts: {this.props.displayPost(this.props.posts)}
</div>
);
}
}
I'm trying to build a todo page where I can input todos in my input field. All todos will be rendered below. I managed to build a form where I can type in a todo title and send it to my database. A small problem I'm having here is that I need to refresh the page after pushing the add button to see the new list. I assume this is because I use componentDidMount and this updates only at page refresh. Any idea how I can do this at page refresh (componentDidUpdate) AND at state change ?
FRONT-END
import React from 'react'
import './Todo.css'
import Todoitem from '../components/Todoitem'
import axios from 'axios'
import qs from "qs"
import DefaultLayout from "../layout/Default"
class Todo extends React.Component {
constructor() {
super()
this.state = {
title:"",
todos:[]
}
this.handleChange=this.handleChange.bind(this)
this.handleSubmit=this.handleSubmit.bind(this)
}
componentDidMount(){
axios({
method: "GET",
url: `${process.env.REACT_APP_API_BASE}/todo`,
withCredentials: true
})
.then(response => {
console.log(response)
let todolist = response.data;
this.setState({todos:todolist})
})
.catch(error => {
console.log("You've made an error when getting the todos charles: ",error)
})
}
handleChange(event){
event.preventDefault()
let name = event.target.name
let value = event.target.value
this.setState({
[name]:value
})
console.log(this.state.title)
}
handleSubmit(event){
event.preventDefault()
if (!this.state.title) {
debugger
}
axios({
method: "POST",
url: `${process.env.REACT_APP_API_BASE}/todo`,
data: qs.stringify({title: this.state.title}),
headers: {"content-type": "application/x-www-form-urlencoded"},
withCredentials: true
})
.then((response) => {
console.log(response)
})
.catch((error) => {
console.log(error.response)
})
}
handleDelete(todoId){
axios
.delete(`${process.env.REACT_APP_API_BASE}/todo/${todoId}`)
.then(response => {
const remainingTodos = this.state.todos.filter(element => element._id !== todoId)
this.setState({
todos: remainingTodos
})
})
.catch(err => console.log(err))
}
render() {
return (
<div>
<DefaultLayout>
<h1>To-do things for this app</h1>
<h2 className="todotitle">Add your to-do here, Charles!</h2>
<form className="todocontainer" onClick={this.handleSubmit}>
<div className="inputbuttonandfield">
<div className="inputcontainer">
<div className="captionpart">
<label className="captionlabel" htmlFor="title">Add to-do:</label><br></br>
<input className="captionform" type="text" name="title" value={this.state.title} placeholder="Type your to-do here!" onChange={(e) => this.handleChange(e)}></input>
<button className="shootbutton">Add!</button>
</div>
</div>
</div>
</form>
{
this.state.todos.map(element=> (
<div className="todosoverviewlister" key={element._id}>
<Todoitem id={element._id} title={element.title} />
<button className="tododelete" onClick={()=> this.handleDelete(element._id)}>Delete</button>
</div>
))
}
</DefaultLayout>
</div>
)
}
}
export default Todo
Todomodel
const mongoose = require("mongoose")
const Schema = mongoose.Schema
const todoSchema = new Schema({
title: String
})
const Todo = mongoose.model("todos",todoSchema)
module.exports = Todo
BACKEND
//request todos
router.get("/todo", (req,res) => {
Todo
.find()
.then(response => {
res.json(response)
})
.catch(error => {
res.json(error)
})
})
//delete todo
router.delete("/todo/:id", (req,res)=>{
Todo
.findByIdAndDelete(req.params.id)
.then(response => {
res.json(response)
})
.catch(error => {
res.json(error)
})
})
You can either update the state or sync up with database by sending another GET. Let me break it down into 2 solutions:
Just update the state
Make a GET request after the POST request and update the state
Just update the state
// you code ...
handleSubmit(event){
event.preventDefault()
const newTodo = { title: this.state.title }; // extract your todo into const
axios({
method: "POST",
url: `${process.env.REACT_APP_API_BASE}/todo`,
data: qs.stringify(newTodo), // send todo in the POST
headers: {"content-type": "application/x-www-form-urlencoded"},
withCredentials: true
})
.then((response) => {
console.log(response)
this.setState(prevState => ({ // immutably update the state
todos: [...prevState.todos, newTodo]
}));
})
.catch((error) => {
console.log(error.response)
})
}
// your code ...
Send GET after POST:
// your Todo component
class Todo extends React.Component {
constructor() {
super();
this.state = {
title: "",
todos: [],
};
this.handleChange = this.handleChange.bind(this);
this.handleSubmit = this.handleSubmit.bind(this);
}
// extract method for loading TODOs (your previous componentDidMount)
loadTodos = () => {
axios({
method: "GET",
url: `${process.env.REACT_APP_API_BASE}/todo`,
withCredentials: true,
})
.then((response) => {
console.log(response);
let todolist = response.data;
this.setState({ todos: todolist });
})
.catch((error) => {
console.log(
"You've made an error when getting the todos charles: ",
error
);
});
}
componentDidMount() {
this.loadTodos(); // use the extracted method
}
handleChange(event) {
event.preventDefault();
let name = event.target.name;
let value = event.target.value;
this.setState({
[name]: value,
});
console.log(this.state.title);
}
handleSubmit(event) {
event.preventDefault();
if (!this.state.title) {
debugger;
}
axios({
method: "POST",
url: `${process.env.REACT_APP_API_BASE}/todo`,
data: qs.stringify({ title: this.state.title }),
headers: { "content-type": "application/x-www-form-urlencoded" },
withCredentials: true,
})
.then((response) => {
console.log(response);
this.loadTodos(); // use the extracted method
})
.catch((error) => {
console.log(error.response);
});
}
handleDelete(todoId) {
axios
.delete(`${process.env.REACT_APP_API_BASE}/todo/${todoId}`)
.then((response) => {
const remainingTodos = this.state.todos.filter(
(element) => element._id !== todoId
);
this.setState({
todos: remainingTodos,
});
})
.catch((err) => console.log(err));
}
render() {
return (
<div>
<DefaultLayout>
<h1>To-do things for this app</h1>
<h2 className="todotitle">Add your to-do here, Charles!</h2>
<form className="todocontainer" onClick={this.handleSubmit}>
<div className="inputbuttonandfield">
<div className="inputcontainer">
<div className="captionpart">
<label className="captionlabel" htmlFor="title">
Add to-do:
</label>
<br></br>
<input
className="captionform"
type="text"
name="title"
value={this.state.title}
placeholder="Type your to-do here!"
onChange={(e) => this.handleChange(e)}
></input>
<button className="shootbutton">Add!</button>
</div>
</div>
</div>
</form>
{this.state.todos.map((element) => (
<div className="todosoverviewlister" key={element._id}>
<Todoitem id={element._id} title={element.title} />
<button
className="tododelete"
onClick={() => this.handleDelete(element._id)}
>
Delete
</button>
</div>
))}
</DefaultLayout>
</div>
);
}
}
export default Todo;
I believe the issue is that you're not updating the state when you submit (during the add operation). In your delete, you correctly keep the list in state synced with the list on the server by removing the element locally as well. In the add, you should to something similar by adding the new element to the list in state (or more precisely, make a deep copy and overwrite the one in state). That should do it.
There is no need to refetch the entire list from the server unless there are multiple users operating on the same list. If that's the case, you can add a get() call in the response of your submit. As long as the response of that operation writes to state, it will update correctly. But again, avoid that unless you need it as it will make your app slower and less responsive.
I'm trying to dynamically add inputs when the user clicks the button to add a question.
Usually doing a controlled form is easy as your know what the field names are. But in this situation they are dynamic.
I've got a working solution but it mutates the state.
Is there a better way to do this?
Thanks
JSX
import React, { Component } from 'react';
import axios from 'axios';
import { saveAs } from 'file-saver';
class Form extends Component {
constructor(props) {
super(props);
this.onChange = this.onChange.bind(this);
this.handleForm = this.handleForm.bind(this);
this.addQuestion = this.addQuestion.bind(this);
this.removeQuestion = this.removeQuestion.bind(this);
this.state = {
questions: []
}
}
onChange(e, i) {
this.state.questions[i] = e.target.value;
this.setState({
questions: this.state.questions
})
}
handleForm(e) {
e.preventDefault();
const body = {
questions: this.state.questions
};
axios.post('/api/pdfs/create', body)
.then(() => axios.get('/api/pdfs/fetch', { responseType: 'blob' }))
.then((res) => {
const pdfBlob = new Blob([res.data], { type: 'application/pdf' });
return saveAs(pdfBlob, 'questions.pdf');
})
.catch(error => {
console.log(error.response)
});
}
addQuestion() {
this.setState({
questions: [...this.state.questions, '']
});
}
removeQuestion(index) {
this.setState({
questions: this.state.questions.filter((question, i) => i !== index)
});
}
render() {
return (
<div>
<button onClick={this.addQuestion}>Add Question</button>
<form onSubmit={this.handleForm}>
{this.state.questions.map((question, index) => (
<div key={index}>
<input type="text" name={`question-${question}`} onChange={(e) => this.onChange(e, index)} />
<button type="button" onClick={() => this.removeQuestion(index)}>x</button>
</div>
))}
<button type="submit">Submit</button>
</form>
</div>
);
}
}
export default Form;
You are mutating the state only in your onChange call, and that can be fixed easily:
onChange(e, i) {
this.setState({
questions: this.state.questions.map((v, i2) => i === i2 ? e.target.value : v),
});
}
(This won't change the functionality though, its just a "best practice improvement")
I've been reviewing my HTTP/AJAX project and was able to implement my get, post and delete. But I tried to implement the put request on my own and have been stuck on it for two days (I know).
My understanding is that there should be the axios request in an event handler, and then you bind the handler. My put request has the id and is updating, but the id (friend.id) is only replaced by an empty string. Put request is working in the server and updates the data correctly. So I see my problem is in React.
I looked up help guides on editing state and applying it to the put request. I initialized editing: false as state, made a handler for setting editing to true and did an onChange on each input in the form for editing at the bottom. But I see that I'm not understanding how the handleUpdating event handler should connect with put (I commented them below), or if I needed it.
Here is my file hierarchy:
Here is the server's put request (located in server.js):
app.put('/friends/:id', (req, res) => {
const { id } = req.params;
let friendIndex = friends.findIndex(friend => friend.id == id);
if (friendIndex >= 0) {
friends[friendIndex] = { ...friends[friendIndex], ...req.body };
res.status(200).json(friends);
} else {
res
.status(404)
.json({ message: `The friend with id ${id} does not exist.` });
}
});
And here is the code in my React Application (located in Friendslist.js):
import React from 'react';
import axios from 'axios';
const API_URL = 'http://localhost:5000/friends';
class FriendsList extends React.Component {
constructor() {
super();
this.state = {
friends: [],
editing: false,
loading: true,
showComponent: false,
name: '',
age: '',
email: ''
}
}
componentDidMount() {
axios
.get(`${API_URL}`)
.then(response => {
console.log(response.data);
this.setState({ friends: response.data, loading: false });
})
.catch(error => {
console.log('There was an error', error);
})
}
onClickComponent = () => {
this.setState({ showComponent: true });
}
handleName = (event) => {
event.preventDefault();
this.setState({
name: event.target.value
});
}
handleAge = (event) => {
event.preventDefault();
this.setState({
age: event.target.value
});
}
handleEmail = (event) => {
event.preventDefault();
this.setState({
email: event.target.value
});
}
// handleUpdating - setting edit to true
handleUpdating = (event) => {
this.setState({ editing: true })
}
onClickComponent = () => {
this.setState({ showComponent: true });
}
handleDelete = (id) => {
axios
.delete(`${API_URL}/${id}`)
.then(response => {
this.setState({
friends: response.data
})
console.log(response.data)
})
.catch(error => {
console.log(error)
})
};
handleSubmit = (event) => {
event.preventDefault();
axios.post(`${API_URL}`, {
name: this.state.name,
age: this.state.age,
email: this.state.email
})
.then(response => {
this.setState({ friends: response.data });
})
.catch(error => {
console.log(error);
});
}
// This is the put request
handleEdit = (id) => {
axios.put(`${API_URL}/${id}`, {
name: this.state.name,
age: this.state.age,
email: this.state.email
})
.then(response => {
this.setState({ friends: response.data });
})
.catch(error => {
console.log(error);
});
}
render() {
if (this.state.loading) {
return <h1>Loading Friends....</h1>
} else if (!this.state.loading) {
return (
<div>
<form onSubmit={this.handleSubmit}>
<label>
Name:
<input type="text" value={this.state.name} onChange={this.handleName} />
</label>
<label>
Age:
<input type="text" value={this.state.age} onChange={this.handleAge} />
</label>
<label>
Email:
<input type="text" value={this.state.email} onChange={this.handleEmail} />
</label>
<input type="submit" value="Submit" />
</form>
<div>{this.state.friends.map((friend) => {
return (
<div onChange={() => this.handleUpdating} key={friend.id} className="friend">
<div className="friend-name">{friend.name}</div>
<div className="friend-age">{`Age: ${friend.age}`}</div>
<div className="friend-email">{`Email: ${friend.email}`}</div>
<button onClick={() => this.handleDelete(friend.id)}>Delete</button>
<button onClick={this.onClickComponent}>Edit</button>
{this.state.showComponent ? <Form handleEdit={() => this.handleEdit(friend.id)} /> : null}
</div>
);
})}
</div>
</div>
);
}
}
}
const Form = (props) => {
return (
<form onSubmit={() => props.handleEdit(props.id)}>
<label>
Name: <input type="text" value={props.name} onChange={this.handleUpdating} />
</label>
<label>
Age: <input type="text" value={props.age} onChange={this.handleUpdating} />
</label>
<label>
Email: <input type="text" value={props.email} onChange={this.handleUpdating} />
</label>
<input type="submit" value="Update" />
</form>
);
}
export default FriendsList;
I appreciate any help and/or feedback!
enter code here
import { connect } from 'react-redux';
import api from '../../services/api';
import * as actions from '../../store/actions';
updateTool = (id) => {
console.tron.log('edit !!!');
this.setState({ isEdit: true });
const modifyTool = {
id: this.props.id,
title: this.state.title,
link: this.state.link,
description: this.state.description,
tags: this.state.tags,
};
api
.put(`/tools/${id}`, modifyTool)
.then((res) => {
console.log(res.data);
})
.catch((error) => {
console.log(error);
});
};
{/* form Modal Update */}
<section>
<Modal
visible={this.state.showModal}
width="400"
height="370"
effect="fadeInUp"
onClickAway={() => this.closeModal()}
>
<FormModal>
<form onSubmit={this.updateTool}>
<div>
<span>Update tool</span>
<label>Tool Name</label>
<input
type="text"
onChange={this.handleChange}
value={tool.title}
name="title"
/>
<label>Tool Link</label>
<input
type="text"
onChange={this.handleChange}
value={this.props.link}
name="link"
/>
<label>Tool description</label>
<textarea
cols={20}
rows={5}
name="description"
onChange={this.handleChange}
value={this.state.description}
/>
<label>Tags</label>
<input
type="text"
onChange={this.handleChange}
value={this.state.tags}
name="tags"
/>
</div>
<AlignHorizontalRight>
<button>Cancel</button>
<div>
<input
type="button"
value="EDIT"
type="submit"
onClick={() => this.updateTool(tool.id)}
/>
</div>
</AlignHorizontalRight>
</form>
</FormModal>
</Modal>
</section>
const mapDispatchToProps = dispatch => ({
removeTool: (id) => {
dispatch(actions.removeTool(id));
},
updateTool: (id, title, link, description, tags) => {
dispatch(actions.updateTool(id, title, link, description, tags));
},
});
export default connect(
null,
mapDispatchToProps,
)(Content);
actions/index.js
export const ADD_TOOL = 'ADD_TOOL';
export const REMOVE_TOOL = 'REMOVE_TOOL';
export const UPDATE_TOOL = 'UPDATE_TOOL';
const nextId = 0;
export function addTool(title, link, description, tags) {
return {
type: ADD_TOOL,
id: nextId,
title,
link,
description,
tags,
};
}
export function removeTool(id) {
return {
type: REMOVE_TOOL,
id,
};
}
export function updateTool(id, title, link, description, tags) {
return {
type: UPDATE_TOOL,
id,
title,
link,
description,
tags,
};
}
store/index.js
import { createStore } from 'redux';
const store = createStore(() => {});
export default store;
reducers/index.js
import { combineReducers } from 'redux';
import tool from './tool';
const store = combineReducers({
tool,
});
export default store;
reducers/tool.js
import { ADD_TOOL, REMOVE_TOOL, UPDATE_TOOL } from '../actions';
const INITIAL_STATE = [];
export default function Tool(state = INITIAL_STATE, action) {
switch (action.type) {
case ADD_TOOL:
return [
...state,
{
id: action.id,
title: action.title,
link: action.link,
description: action.description,
tags: action.tags,
},
];
case REMOVE_TOOL:
return state.filter(({ id }) => id !== action.id);
case UPDATE_TOOL:
return state.map(tool => (tool.id === action.id ? { ...tool, ...action } : tool));
default:
return state;
}
}
enter code here
=================================
friend Dev, here is all the data I developed to create a CRUD and with me it worked fine, I'm just having difficulty clicking a record, and this record appears in the form to edit, the main one is doing what it is, API data.
Good luck in your studies.
NOTE: I'm assuming that you already know how to use the data described above, it's not in the order, but just coding or paste correctly will work.