简体   繁体   中英

How do I update state with axios put request on my React application? (React/Node Express)

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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM