Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/450.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/reactjs/21.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 如何防止对已卸载组件上的异步请求进行响应状态更新?_Javascript_Reactjs_Mern - Fatal编程技术网

Javascript 如何防止对已卸载组件上的异步请求进行响应状态更新?

Javascript 如何防止对已卸载组件上的异步请求进行响应状态更新?,javascript,reactjs,mern,Javascript,Reactjs,Mern,我正在开发一个mernstack应用程序,其中我有一个自定义的钩子,用于加载到上下文API中的useReducer状态和分派函数的API请求。通常GET请求在页面加载时运行平稳,但每次使用POST、PATCH、PUT和DELETE请求函数时,都会导致组件卸载并出现以下错误: 警告:无法对未安装的组件执行React状态更新。这是一个no-op,但它表示应用程序中存在内存泄漏。要修复此问题,请取消useEffect清理函数中的所有订阅和异步任务 每当我刷新页面并看到更改时,错误就会消失。如何防止对已

我正在开发一个mernstack应用程序,其中我有一个自定义的钩子,用于加载到上下文API中的useReducer状态和分派函数的API请求。通常GET请求在页面加载时运行平稳,但每次使用POST、PATCH、PUT和DELETE请求函数时,都会导致组件卸载并出现以下错误:

警告:无法对未安装的组件执行React状态更新。这是一个no-op,但它表示应用程序中存在内存泄漏。要修复此问题,请取消useEffect清理函数中的所有订阅和异步任务

每当我刷新页面并看到更改时,错误就会消失。如何防止对已卸载组件上的异步请求进行响应状态更新

数据库设置

const mongodb = require('mongodb');
const { MongoClient, ObjectID } = mongodb;
require('dotenv').config();
const mongourl = process.env.MONGO_URI;
const db_name = process.env.DB_NAME;
let db;

async function startConnection(cb) {
  let client;    
  try {
    client = await MongoClient.connect(mongourl, {
      useNewUrlParser: true,
      useUnifiedTopology: true,
    });
    db = client.db(db_name);
    await cb();
  } catch (err) {
    await cb(err);
  }
}

const getDb = () => {
  return db;
};

const getPrimaryKey = (_id) => {
  return ObjectID(_id);
};

module.exports = { db, startConnection, getDb, getPrimaryKey };
服务器:

const express = require('express');
require('dotenv').config();
const port = process.env.PORT || 8000;
const db = require('./db');
const db_col = process.env.DB_COL;
const router = express.Router();
let status;

db.startConnection((err) => {
  if (err) {
    status = `Unable to connect to the database ${err}`;
    console.log(status);
  } else {
    status = 'Connected to the database';
    console.log(status);
  }
});

const app = express();
app.use(express.json());
app.use(express.urlencoded({ extended: true }));
app.use('/list', router);

router.get('/', (req, res) => {
  db.getDb()
    .collection(db_col)
    .find({})
    .toArray((err, docs) => {
      if (err) {
        console.log(err);
      }
      res.json(docs);
      console.log(docs);
    });
});

router.post('/', (req, res) => {
  const newlist = req.body;
  const { list_name, list_items } = newlist;
  db.getDb()
    .collection(db_col)
    .insertOne({ list_name, list_items }, (err, docs) => {
      if (err) {
        console.log(err);
      }
      res.redirect('/');
      console.log(docs);
    });
});

router.patch('/:id', (req, res) => {
  const paramID = req.params.id;
  const listname = req.body.list_name;
  db.getDb()
    .collection(db_col)
    .updateOne(
      { _id: db.getPrimaryKey(paramID) },
      { $set: { list_name: listname } },
      (err, docs) => {
        if (err) {
          console.log(err);
        }
        res.redirect('/');
        console.log(docs);
      }
    );
});

router.put('/:id', (req, res) => {
  const paramID = req.params.id;
  const listitems = req.body.list_items;
  db.getDb()
    .collection(db_col)
    .updateOne(
      { _id: db.getPrimaryKey(paramID) },
      { $set: { list_items: listitems } },
      (err, docs) => {
        if (err) {
          console.log(err);
        }
        res.redirect('/');
        console.log(docs);
      }
    );
});

router.delete('/:id', (req, res) => {
  const paramID = req.params.id;
  db.getDb()
    .collection(db_col)
    .deleteOne({ _id: db.getPrimaryKey(paramID) }, (err, docs) => {
      if (err) {
        console.log(err);
      }
      res.redirect('/');
      console.log(docs);
    });
});

app.listen(port, console.log(`Server listening to port: ${port}`));
import { LOADING, PROCESSING_REQUEST, HANDLING_ERROR } from './actionTypes';

const loading = () => {
  return {
    type: LOADING,
  };
};

const processingRequest = (params) => {
  return {
    type: PROCESSING_REQUEST,
    response: params,
  };
};

const handlingError = () => {
  return {
    type: HANDLING_ERROR,
  };
};

export { loading, processingRequest, handlingError };
import {
  LOADING,
  PROCESSING_REQUEST,
  HANDLING_ERROR,
} from './actions/actionTypes';

export const initialState = {
  isError: false,
  isLoading: false,
  data: [],
};

const listReducer = (state, { type, response }) => {
  switch (type) {
    case LOADING:
      return {
        ...state,
        isLoading: true,
        isError: false
      };
    case PROCESSING_REQUEST:
      return {
        ...state,
        isLoading: false,
        isError: false,
        data: response,
      };
    case HANDLING_ERROR:
      return {
        ...state,
        isLoading: false,
        isError: true
      };
    default:
      throw new Error();
  }
};

export default listReducer;
import { useEffect, useCallback, useReducer } from 'react';
import axios from 'axios';
import listReducer, { initialState } from '../../context/reducers/reducers';
import {
  loading,
  processingRequest,
  handlingError,
} from '../../context/reducers/actions/actionCreators';

const useApiReq = () => {
  const [state, dispatch] = useReducer(listReducer, initialState);

  const getRequest = useCallback(async () => {
    dispatch(loading());
    try {
      const response = await axios.get('/list');
      dispatch(processingRequest(response.data));
    } catch (err) {
      dispatch(handlingError);
    }
  }, []);

  const postRequest = useCallback(async (entry) => {
    dispatch(loading());
    try {
      const response = await axios.post('/list', entry);
      dispatch(processingRequest(response.data));
    } catch (err) {
      dispatch(handlingError);
    }
  }, []);

  const patchRequest = useCallback(async (id, updated_entry) => {
    dispatch(loading());
    try {
      const response = await axios.patch(`/list/${id}`, updated_entry);
      dispatch(processingRequest(response.data));
    } catch (err) {
      dispatch(handlingError);
    }
  }, []);

  const putRequest = useCallback(async (id, updated_entry) => {
    dispatch(loading());
    try {
      const response = await axios.put(`/list/${id}`, updated_entry);
      dispatch(processingRequest(response.data));
    } catch (err) {
      dispatch(handlingError);
    }
  }, []);

  const deleteRequest = useCallback(async (id) => {
    dispatch(loading());
    try {
      const response = await axios.delete(`/list/${id}`);
      dispatch(processingRequest(response.data));
    } catch (err) {
      dispatch(handlingError);
    }
  }, []);

  return [
    state,
    getRequest,
    postRequest,
    patchRequest,
    putRequest,
    deleteRequest,
  ];
};

export default useApiReq;
import React from 'react';
import AppContextProvider from './context/AppContext';
import Header from './components/header/Header';
import Main from './components/main/Main';
import './stylesheets/styles.scss';

function App() {
  return (
    <AppContextProvider>
      <div className='App'>
        <Header />
        <Main />
      </div>
    </AppContextProvider>
  );
}

export default App;
行动:

const express = require('express');
require('dotenv').config();
const port = process.env.PORT || 8000;
const db = require('./db');
const db_col = process.env.DB_COL;
const router = express.Router();
let status;

db.startConnection((err) => {
  if (err) {
    status = `Unable to connect to the database ${err}`;
    console.log(status);
  } else {
    status = 'Connected to the database';
    console.log(status);
  }
});

const app = express();
app.use(express.json());
app.use(express.urlencoded({ extended: true }));
app.use('/list', router);

router.get('/', (req, res) => {
  db.getDb()
    .collection(db_col)
    .find({})
    .toArray((err, docs) => {
      if (err) {
        console.log(err);
      }
      res.json(docs);
      console.log(docs);
    });
});

router.post('/', (req, res) => {
  const newlist = req.body;
  const { list_name, list_items } = newlist;
  db.getDb()
    .collection(db_col)
    .insertOne({ list_name, list_items }, (err, docs) => {
      if (err) {
        console.log(err);
      }
      res.redirect('/');
      console.log(docs);
    });
});

router.patch('/:id', (req, res) => {
  const paramID = req.params.id;
  const listname = req.body.list_name;
  db.getDb()
    .collection(db_col)
    .updateOne(
      { _id: db.getPrimaryKey(paramID) },
      { $set: { list_name: listname } },
      (err, docs) => {
        if (err) {
          console.log(err);
        }
        res.redirect('/');
        console.log(docs);
      }
    );
});

router.put('/:id', (req, res) => {
  const paramID = req.params.id;
  const listitems = req.body.list_items;
  db.getDb()
    .collection(db_col)
    .updateOne(
      { _id: db.getPrimaryKey(paramID) },
      { $set: { list_items: listitems } },
      (err, docs) => {
        if (err) {
          console.log(err);
        }
        res.redirect('/');
        console.log(docs);
      }
    );
});

router.delete('/:id', (req, res) => {
  const paramID = req.params.id;
  db.getDb()
    .collection(db_col)
    .deleteOne({ _id: db.getPrimaryKey(paramID) }, (err, docs) => {
      if (err) {
        console.log(err);
      }
      res.redirect('/');
      console.log(docs);
    });
});

app.listen(port, console.log(`Server listening to port: ${port}`));
import { LOADING, PROCESSING_REQUEST, HANDLING_ERROR } from './actionTypes';

const loading = () => {
  return {
    type: LOADING,
  };
};

const processingRequest = (params) => {
  return {
    type: PROCESSING_REQUEST,
    response: params,
  };
};

const handlingError = () => {
  return {
    type: HANDLING_ERROR,
  };
};

export { loading, processingRequest, handlingError };
import {
  LOADING,
  PROCESSING_REQUEST,
  HANDLING_ERROR,
} from './actions/actionTypes';

export const initialState = {
  isError: false,
  isLoading: false,
  data: [],
};

const listReducer = (state, { type, response }) => {
  switch (type) {
    case LOADING:
      return {
        ...state,
        isLoading: true,
        isError: false
      };
    case PROCESSING_REQUEST:
      return {
        ...state,
        isLoading: false,
        isError: false,
        data: response,
      };
    case HANDLING_ERROR:
      return {
        ...state,
        isLoading: false,
        isError: true
      };
    default:
      throw new Error();
  }
};

export default listReducer;
import { useEffect, useCallback, useReducer } from 'react';
import axios from 'axios';
import listReducer, { initialState } from '../../context/reducers/reducers';
import {
  loading,
  processingRequest,
  handlingError,
} from '../../context/reducers/actions/actionCreators';

const useApiReq = () => {
  const [state, dispatch] = useReducer(listReducer, initialState);

  const getRequest = useCallback(async () => {
    dispatch(loading());
    try {
      const response = await axios.get('/list');
      dispatch(processingRequest(response.data));
    } catch (err) {
      dispatch(handlingError);
    }
  }, []);

  const postRequest = useCallback(async (entry) => {
    dispatch(loading());
    try {
      const response = await axios.post('/list', entry);
      dispatch(processingRequest(response.data));
    } catch (err) {
      dispatch(handlingError);
    }
  }, []);

  const patchRequest = useCallback(async (id, updated_entry) => {
    dispatch(loading());
    try {
      const response = await axios.patch(`/list/${id}`, updated_entry);
      dispatch(processingRequest(response.data));
    } catch (err) {
      dispatch(handlingError);
    }
  }, []);

  const putRequest = useCallback(async (id, updated_entry) => {
    dispatch(loading());
    try {
      const response = await axios.put(`/list/${id}`, updated_entry);
      dispatch(processingRequest(response.data));
    } catch (err) {
      dispatch(handlingError);
    }
  }, []);

  const deleteRequest = useCallback(async (id) => {
    dispatch(loading());
    try {
      const response = await axios.delete(`/list/${id}`);
      dispatch(processingRequest(response.data));
    } catch (err) {
      dispatch(handlingError);
    }
  }, []);

  return [
    state,
    getRequest,
    postRequest,
    patchRequest,
    putRequest,
    deleteRequest,
  ];
};

export default useApiReq;
import React from 'react';
import AppContextProvider from './context/AppContext';
import Header from './components/header/Header';
import Main from './components/main/Main';
import './stylesheets/styles.scss';

function App() {
  return (
    <AppContextProvider>
      <div className='App'>
        <Header />
        <Main />
      </div>
    </AppContextProvider>
  );
}

export default App;
减速器:

const express = require('express');
require('dotenv').config();
const port = process.env.PORT || 8000;
const db = require('./db');
const db_col = process.env.DB_COL;
const router = express.Router();
let status;

db.startConnection((err) => {
  if (err) {
    status = `Unable to connect to the database ${err}`;
    console.log(status);
  } else {
    status = 'Connected to the database';
    console.log(status);
  }
});

const app = express();
app.use(express.json());
app.use(express.urlencoded({ extended: true }));
app.use('/list', router);

router.get('/', (req, res) => {
  db.getDb()
    .collection(db_col)
    .find({})
    .toArray((err, docs) => {
      if (err) {
        console.log(err);
      }
      res.json(docs);
      console.log(docs);
    });
});

router.post('/', (req, res) => {
  const newlist = req.body;
  const { list_name, list_items } = newlist;
  db.getDb()
    .collection(db_col)
    .insertOne({ list_name, list_items }, (err, docs) => {
      if (err) {
        console.log(err);
      }
      res.redirect('/');
      console.log(docs);
    });
});

router.patch('/:id', (req, res) => {
  const paramID = req.params.id;
  const listname = req.body.list_name;
  db.getDb()
    .collection(db_col)
    .updateOne(
      { _id: db.getPrimaryKey(paramID) },
      { $set: { list_name: listname } },
      (err, docs) => {
        if (err) {
          console.log(err);
        }
        res.redirect('/');
        console.log(docs);
      }
    );
});

router.put('/:id', (req, res) => {
  const paramID = req.params.id;
  const listitems = req.body.list_items;
  db.getDb()
    .collection(db_col)
    .updateOne(
      { _id: db.getPrimaryKey(paramID) },
      { $set: { list_items: listitems } },
      (err, docs) => {
        if (err) {
          console.log(err);
        }
        res.redirect('/');
        console.log(docs);
      }
    );
});

router.delete('/:id', (req, res) => {
  const paramID = req.params.id;
  db.getDb()
    .collection(db_col)
    .deleteOne({ _id: db.getPrimaryKey(paramID) }, (err, docs) => {
      if (err) {
        console.log(err);
      }
      res.redirect('/');
      console.log(docs);
    });
});

app.listen(port, console.log(`Server listening to port: ${port}`));
import { LOADING, PROCESSING_REQUEST, HANDLING_ERROR } from './actionTypes';

const loading = () => {
  return {
    type: LOADING,
  };
};

const processingRequest = (params) => {
  return {
    type: PROCESSING_REQUEST,
    response: params,
  };
};

const handlingError = () => {
  return {
    type: HANDLING_ERROR,
  };
};

export { loading, processingRequest, handlingError };
import {
  LOADING,
  PROCESSING_REQUEST,
  HANDLING_ERROR,
} from './actions/actionTypes';

export const initialState = {
  isError: false,
  isLoading: false,
  data: [],
};

const listReducer = (state, { type, response }) => {
  switch (type) {
    case LOADING:
      return {
        ...state,
        isLoading: true,
        isError: false
      };
    case PROCESSING_REQUEST:
      return {
        ...state,
        isLoading: false,
        isError: false,
        data: response,
      };
    case HANDLING_ERROR:
      return {
        ...state,
        isLoading: false,
        isError: true
      };
    default:
      throw new Error();
  }
};

export default listReducer;
import { useEffect, useCallback, useReducer } from 'react';
import axios from 'axios';
import listReducer, { initialState } from '../../context/reducers/reducers';
import {
  loading,
  processingRequest,
  handlingError,
} from '../../context/reducers/actions/actionCreators';

const useApiReq = () => {
  const [state, dispatch] = useReducer(listReducer, initialState);

  const getRequest = useCallback(async () => {
    dispatch(loading());
    try {
      const response = await axios.get('/list');
      dispatch(processingRequest(response.data));
    } catch (err) {
      dispatch(handlingError);
    }
  }, []);

  const postRequest = useCallback(async (entry) => {
    dispatch(loading());
    try {
      const response = await axios.post('/list', entry);
      dispatch(processingRequest(response.data));
    } catch (err) {
      dispatch(handlingError);
    }
  }, []);

  const patchRequest = useCallback(async (id, updated_entry) => {
    dispatch(loading());
    try {
      const response = await axios.patch(`/list/${id}`, updated_entry);
      dispatch(processingRequest(response.data));
    } catch (err) {
      dispatch(handlingError);
    }
  }, []);

  const putRequest = useCallback(async (id, updated_entry) => {
    dispatch(loading());
    try {
      const response = await axios.put(`/list/${id}`, updated_entry);
      dispatch(processingRequest(response.data));
    } catch (err) {
      dispatch(handlingError);
    }
  }, []);

  const deleteRequest = useCallback(async (id) => {
    dispatch(loading());
    try {
      const response = await axios.delete(`/list/${id}`);
      dispatch(processingRequest(response.data));
    } catch (err) {
      dispatch(handlingError);
    }
  }, []);

  return [
    state,
    getRequest,
    postRequest,
    patchRequest,
    putRequest,
    deleteRequest,
  ];
};

export default useApiReq;
import React from 'react';
import AppContextProvider from './context/AppContext';
import Header from './components/header/Header';
import Main from './components/main/Main';
import './stylesheets/styles.scss';

function App() {
  return (
    <AppContextProvider>
      <div className='App'>
        <Header />
        <Main />
      </div>
    </AppContextProvider>
  );
}

export default App;
API请求的自定义挂钩:

const express = require('express');
require('dotenv').config();
const port = process.env.PORT || 8000;
const db = require('./db');
const db_col = process.env.DB_COL;
const router = express.Router();
let status;

db.startConnection((err) => {
  if (err) {
    status = `Unable to connect to the database ${err}`;
    console.log(status);
  } else {
    status = 'Connected to the database';
    console.log(status);
  }
});

const app = express();
app.use(express.json());
app.use(express.urlencoded({ extended: true }));
app.use('/list', router);

router.get('/', (req, res) => {
  db.getDb()
    .collection(db_col)
    .find({})
    .toArray((err, docs) => {
      if (err) {
        console.log(err);
      }
      res.json(docs);
      console.log(docs);
    });
});

router.post('/', (req, res) => {
  const newlist = req.body;
  const { list_name, list_items } = newlist;
  db.getDb()
    .collection(db_col)
    .insertOne({ list_name, list_items }, (err, docs) => {
      if (err) {
        console.log(err);
      }
      res.redirect('/');
      console.log(docs);
    });
});

router.patch('/:id', (req, res) => {
  const paramID = req.params.id;
  const listname = req.body.list_name;
  db.getDb()
    .collection(db_col)
    .updateOne(
      { _id: db.getPrimaryKey(paramID) },
      { $set: { list_name: listname } },
      (err, docs) => {
        if (err) {
          console.log(err);
        }
        res.redirect('/');
        console.log(docs);
      }
    );
});

router.put('/:id', (req, res) => {
  const paramID = req.params.id;
  const listitems = req.body.list_items;
  db.getDb()
    .collection(db_col)
    .updateOne(
      { _id: db.getPrimaryKey(paramID) },
      { $set: { list_items: listitems } },
      (err, docs) => {
        if (err) {
          console.log(err);
        }
        res.redirect('/');
        console.log(docs);
      }
    );
});

router.delete('/:id', (req, res) => {
  const paramID = req.params.id;
  db.getDb()
    .collection(db_col)
    .deleteOne({ _id: db.getPrimaryKey(paramID) }, (err, docs) => {
      if (err) {
        console.log(err);
      }
      res.redirect('/');
      console.log(docs);
    });
});

app.listen(port, console.log(`Server listening to port: ${port}`));
import { LOADING, PROCESSING_REQUEST, HANDLING_ERROR } from './actionTypes';

const loading = () => {
  return {
    type: LOADING,
  };
};

const processingRequest = (params) => {
  return {
    type: PROCESSING_REQUEST,
    response: params,
  };
};

const handlingError = () => {
  return {
    type: HANDLING_ERROR,
  };
};

export { loading, processingRequest, handlingError };
import {
  LOADING,
  PROCESSING_REQUEST,
  HANDLING_ERROR,
} from './actions/actionTypes';

export const initialState = {
  isError: false,
  isLoading: false,
  data: [],
};

const listReducer = (state, { type, response }) => {
  switch (type) {
    case LOADING:
      return {
        ...state,
        isLoading: true,
        isError: false
      };
    case PROCESSING_REQUEST:
      return {
        ...state,
        isLoading: false,
        isError: false,
        data: response,
      };
    case HANDLING_ERROR:
      return {
        ...state,
        isLoading: false,
        isError: true
      };
    default:
      throw new Error();
  }
};

export default listReducer;
import { useEffect, useCallback, useReducer } from 'react';
import axios from 'axios';
import listReducer, { initialState } from '../../context/reducers/reducers';
import {
  loading,
  processingRequest,
  handlingError,
} from '../../context/reducers/actions/actionCreators';

const useApiReq = () => {
  const [state, dispatch] = useReducer(listReducer, initialState);

  const getRequest = useCallback(async () => {
    dispatch(loading());
    try {
      const response = await axios.get('/list');
      dispatch(processingRequest(response.data));
    } catch (err) {
      dispatch(handlingError);
    }
  }, []);

  const postRequest = useCallback(async (entry) => {
    dispatch(loading());
    try {
      const response = await axios.post('/list', entry);
      dispatch(processingRequest(response.data));
    } catch (err) {
      dispatch(handlingError);
    }
  }, []);

  const patchRequest = useCallback(async (id, updated_entry) => {
    dispatch(loading());
    try {
      const response = await axios.patch(`/list/${id}`, updated_entry);
      dispatch(processingRequest(response.data));
    } catch (err) {
      dispatch(handlingError);
    }
  }, []);

  const putRequest = useCallback(async (id, updated_entry) => {
    dispatch(loading());
    try {
      const response = await axios.put(`/list/${id}`, updated_entry);
      dispatch(processingRequest(response.data));
    } catch (err) {
      dispatch(handlingError);
    }
  }, []);

  const deleteRequest = useCallback(async (id) => {
    dispatch(loading());
    try {
      const response = await axios.delete(`/list/${id}`);
      dispatch(processingRequest(response.data));
    } catch (err) {
      dispatch(handlingError);
    }
  }, []);

  return [
    state,
    getRequest,
    postRequest,
    patchRequest,
    putRequest,
    deleteRequest,
  ];
};

export default useApiReq;
import React from 'react';
import AppContextProvider from './context/AppContext';
import Header from './components/header/Header';
import Main from './components/main/Main';
import './stylesheets/styles.scss';

function App() {
  return (
    <AppContextProvider>
      <div className='App'>
        <Header />
        <Main />
      </div>
    </AppContextProvider>
  );
}

export default App;
上下文API

import React, { createContext } from 'react';
import useApiReq from '../components/custom-hooks/useApiReq';

export const AppContext = createContext();

const AppContextProvider = (props) => {
  const [
    state,
    getRequest,
    postRequest,
    patchRequest,
    putRequest,
    deleteRequest,
  ] = useApiReq();

  return (
    <AppContext.Provider
      value={{
        state,
        getRequest,
        postRequest,
        patchRequest,
        putRequest,
        deleteRequest,
      }}
    >
      {props.children}
    </AppContext.Provider>
  );
};

export default AppContextProvider;
import React,{createContext}来自“React”;
从“../components/custom hooks/useApiReq”导入useApiReq;
export const AppContext=createContext();
常量AppContextProvider=(道具)=>{
常数[
状态
获取请求,
请求后,
打补丁请求,
请求,
删除请求,
]=useApiReq();
返回(
{props.children}
);
};
导出默认AppContextProvider;
应用程序:

const express = require('express');
require('dotenv').config();
const port = process.env.PORT || 8000;
const db = require('./db');
const db_col = process.env.DB_COL;
const router = express.Router();
let status;

db.startConnection((err) => {
  if (err) {
    status = `Unable to connect to the database ${err}`;
    console.log(status);
  } else {
    status = 'Connected to the database';
    console.log(status);
  }
});

const app = express();
app.use(express.json());
app.use(express.urlencoded({ extended: true }));
app.use('/list', router);

router.get('/', (req, res) => {
  db.getDb()
    .collection(db_col)
    .find({})
    .toArray((err, docs) => {
      if (err) {
        console.log(err);
      }
      res.json(docs);
      console.log(docs);
    });
});

router.post('/', (req, res) => {
  const newlist = req.body;
  const { list_name, list_items } = newlist;
  db.getDb()
    .collection(db_col)
    .insertOne({ list_name, list_items }, (err, docs) => {
      if (err) {
        console.log(err);
      }
      res.redirect('/');
      console.log(docs);
    });
});

router.patch('/:id', (req, res) => {
  const paramID = req.params.id;
  const listname = req.body.list_name;
  db.getDb()
    .collection(db_col)
    .updateOne(
      { _id: db.getPrimaryKey(paramID) },
      { $set: { list_name: listname } },
      (err, docs) => {
        if (err) {
          console.log(err);
        }
        res.redirect('/');
        console.log(docs);
      }
    );
});

router.put('/:id', (req, res) => {
  const paramID = req.params.id;
  const listitems = req.body.list_items;
  db.getDb()
    .collection(db_col)
    .updateOne(
      { _id: db.getPrimaryKey(paramID) },
      { $set: { list_items: listitems } },
      (err, docs) => {
        if (err) {
          console.log(err);
        }
        res.redirect('/');
        console.log(docs);
      }
    );
});

router.delete('/:id', (req, res) => {
  const paramID = req.params.id;
  db.getDb()
    .collection(db_col)
    .deleteOne({ _id: db.getPrimaryKey(paramID) }, (err, docs) => {
      if (err) {
        console.log(err);
      }
      res.redirect('/');
      console.log(docs);
    });
});

app.listen(port, console.log(`Server listening to port: ${port}`));
import { LOADING, PROCESSING_REQUEST, HANDLING_ERROR } from './actionTypes';

const loading = () => {
  return {
    type: LOADING,
  };
};

const processingRequest = (params) => {
  return {
    type: PROCESSING_REQUEST,
    response: params,
  };
};

const handlingError = () => {
  return {
    type: HANDLING_ERROR,
  };
};

export { loading, processingRequest, handlingError };
import {
  LOADING,
  PROCESSING_REQUEST,
  HANDLING_ERROR,
} from './actions/actionTypes';

export const initialState = {
  isError: false,
  isLoading: false,
  data: [],
};

const listReducer = (state, { type, response }) => {
  switch (type) {
    case LOADING:
      return {
        ...state,
        isLoading: true,
        isError: false
      };
    case PROCESSING_REQUEST:
      return {
        ...state,
        isLoading: false,
        isError: false,
        data: response,
      };
    case HANDLING_ERROR:
      return {
        ...state,
        isLoading: false,
        isError: true
      };
    default:
      throw new Error();
  }
};

export default listReducer;
import { useEffect, useCallback, useReducer } from 'react';
import axios from 'axios';
import listReducer, { initialState } from '../../context/reducers/reducers';
import {
  loading,
  processingRequest,
  handlingError,
} from '../../context/reducers/actions/actionCreators';

const useApiReq = () => {
  const [state, dispatch] = useReducer(listReducer, initialState);

  const getRequest = useCallback(async () => {
    dispatch(loading());
    try {
      const response = await axios.get('/list');
      dispatch(processingRequest(response.data));
    } catch (err) {
      dispatch(handlingError);
    }
  }, []);

  const postRequest = useCallback(async (entry) => {
    dispatch(loading());
    try {
      const response = await axios.post('/list', entry);
      dispatch(processingRequest(response.data));
    } catch (err) {
      dispatch(handlingError);
    }
  }, []);

  const patchRequest = useCallback(async (id, updated_entry) => {
    dispatch(loading());
    try {
      const response = await axios.patch(`/list/${id}`, updated_entry);
      dispatch(processingRequest(response.data));
    } catch (err) {
      dispatch(handlingError);
    }
  }, []);

  const putRequest = useCallback(async (id, updated_entry) => {
    dispatch(loading());
    try {
      const response = await axios.put(`/list/${id}`, updated_entry);
      dispatch(processingRequest(response.data));
    } catch (err) {
      dispatch(handlingError);
    }
  }, []);

  const deleteRequest = useCallback(async (id) => {
    dispatch(loading());
    try {
      const response = await axios.delete(`/list/${id}`);
      dispatch(processingRequest(response.data));
    } catch (err) {
      dispatch(handlingError);
    }
  }, []);

  return [
    state,
    getRequest,
    postRequest,
    patchRequest,
    putRequest,
    deleteRequest,
  ];
};

export default useApiReq;
import React from 'react';
import AppContextProvider from './context/AppContext';
import Header from './components/header/Header';
import Main from './components/main/Main';
import './stylesheets/styles.scss';

function App() {
  return (
    <AppContextProvider>
      <div className='App'>
        <Header />
        <Main />
      </div>
    </AppContextProvider>
  );
}

export default App;
从“React”导入React;
从“./context/AppContext”导入AppContextProvider;
从“./components/Header/Header”导入标题;
从“./components/Main/Main”导入Main;
导入“./stylesheets/styles.scss”;
函数App(){
返回(
);
}
导出默认应用程序;
Main: 这是GET请求在初始加载时发生的地方

import React,{useffect,useContext}来自“React”;
从“../../context/AppContext”导入{AppContext};
从“../Sidebar/Sidebar”导入侧栏;
从“../list templates/ParentListItem”导入ParentListItem;
函数Main(){
const{state,getRequest}=useContext(AppContext);
const{isError,isLoading,data}=状态;
useffect(()=>{
getRequest();
},[getRequest]);
返回(
{isLoading&&(

从数据库加载数据

)} {isError&&p className='empty-notif'>出了什么问题

} {data.length==0&&

数据库为空

}
    {data.map((列表)=>( ))}
); } 导出默认主;
侧边栏

import React, { useState } from 'react';
import Modal from 'react-modal';
import AddList from '../modals/AddList';
import DeleteList from '../modals/DeleteList';

/* Modal */
Modal.setAppElement('#root');

function Sidebar() {
  const [addModalStatus, setAddModalStatus] = useState(false);
  const [deleteModalStatus, setDeleteModalStatus] = useState(false);

  const handleAddModal = () => {
    setAddModalStatus((prevState) => !prevState);
  };

  const handleDeleteModal = () => {
    setDeleteModalStatus((prevState) => !prevState);
  };
  return (
    <aside className='sidebar'>
      <nav className='nav'>
        <button className='btn-rec' onClick={handleAddModal}>
          Add
        </button>
        <button className='btn-rec' onClick={handleDeleteModal}>
          Delete
        </button>
      </nav>
      <Modal isOpen={addModalStatus} onRequestClose={handleAddModal}>
        <header className='modal-header'>Create New List</header>
        <div className='modal-body'>
          <AddList exitHandler={handleAddModal} />
        </div>
        <footer className='modal-footer'>
          <button onClick={handleAddModal} className='btn-circle'>
            &times;
          </button>
        </footer>
      </Modal>
      <Modal isOpen={deleteModalStatus} onRequestClose={handleDeleteModal}>
        <header className='modal-header'>Delete List</header>
        <div className='modal-body'>
          <DeleteList exitHandler={handleDeleteModal} />
        </div>
        <footer className='modal-footer'>
          <button onClick={handleDeleteModal} className='btn-circle'>
            &times;
          </button>
        </footer>
      </Modal>
    </aside>
  );
}

export default Sidebar;
import React,{useState}来自“React”;
从“反应模态”导入模态;
从“../modals/AddList”导入AddList;
从“../modals/DeleteList”导入DeleteList;
/*模态*/
Modal.setAppElement(“#根”);
函数边栏(){
常量[addModalStatus,setAddModalStatus]=useState(false);
常量[deleteModalStatus,setDeleteModalStatus]=useState(false);
const handleAddModal=()=>{
setAddModalStatus((prevState)=>!prevState);
};
常量HandleDeleteModel=()=>{
setDeleteModalStatus((prevState)=>!prevState);
};
返回(
添加
删去
创建新列表
&时代;
删除列表
&时代;
);
}
导出默认边栏;
添加模式 这是调用post请求的地方

import React,{useContext,useffect,useState,useRef}来自“React”;
从“../../context/AppContext”导入{AppContext};
常量AddList=({exitHandler})=>{
const{postRequest}=useContext(AppContext);
const[newList,setNewList]=useState({});
const inputRef=useRef(null);
/*在加载集上,将焦点放在输入上*/
useffect(()=>{
inputRef.current.focus();
}, []);
const handleAddList=(e)=>{
e、 预防默认值();
const new_list={
列表名称:inputRef.current.value,
列出项目:[],
};
设置新列表(新列表);
};
常量handleSubmit=(e)=>{
e、 预防默认值();
postRequest(新列表);
exitHandler();
};
返回(
);
};
导出默认地址列表;
删除模式 这是调用删除请求的地方

import React,{useContext,useffect,useState,useRef}来自“React”;
从“../../context/AppContext”导入{AppContext};
常量DeleteList=({exitHandler})=>{
const{state,deleteRequest}=useContext(AppContext);
const{data}=状态;
const selectRef=useRef();
const[targetListId,setTargetListId]=useState();
useffect(()=>{
选择ref.current.focus();
}, []);
useffect(()=>{
setTargetListId(数据[0]。_id);
},[数据];
常量handleDeleteList=(e)=>{
e、 预防默认值();
deleteRequest(targetListId);
exitHandler();
};
常量handleChangeList=(e)=>{
setTargetListId(即target.value);
};
返回(
{data.map((列表)=>(
{list.list_name}
))}
);
};
导出默认删除列表;
父列表: 这就是调用PUT、PATCH请求的地方

import React,{useContext,useState,useffect,useRef}来自“React”;
从'react icons/fa'导入{FaPen,FaCheck};
从“./ChildListItem”导入ChildListItem;
从“../../context/AppContext”导入{AppContext};
从“../../utilities/utilities”导入displayDate;
从'uuid'导入{v4};
函数ParentListItem({u id,list\u name,list\u items}){
常量{patchRequest,put