Reactjs 重复发送两个调度,然后第一个调度丢失
我学习了React Javascript和Redux,现在我遇到了这个问题 这里有一个 试着这样做:Reactjs 重复发送两个调度,然后第一个调度丢失,reactjs,redux,dispatch,Reactjs,Redux,Dispatch,我学习了React Javascript和Redux,现在我遇到了这个问题 这里有一个 试着这样做: 搜索书名“dep” 观看日志显示“搜索url为:”,此时应显示“开始图书搜索…” 我先发送两个Reduxdispatch,然后再发送一个,第一个再也不会发送 基本上是这样的: 我有一个用于学习的图书搜索应用程序,当按Search for a Book时,应用程序中会出现一个dispatch 这是发送状态的类: import { booksActionTypes } from ".
- 搜索书名“dep”
- 观看日志显示“搜索url为:”,此时应显示“开始图书搜索…”
dispatch
,然后再发送一个,第一个再也不会发送
基本上是这样的:
我有一个用于学习的图书搜索应用程序,当按Search for a Book时,应用程序中会出现一个dispatch
这是发送状态的类:
import { booksActionTypes } from "./books.types";
export const showLog = () => ({
type: booksActionTypes.SHOWLOG,
});
export const setLogMessage = (log) => ({
type: booksActionTypes.LOG_MESSAGE,
payload: log,
});
export const clearPosts = () => ({
type: booksActionTypes.CLEAR_POSTS,
});
export const requestStart = () => ({
type: booksActionTypes.REQUEST_START,
});
export const requestSuccess = (booksList) => ({
type: booksActionTypes.REQUEST_SUCCESS,
payload: booksList,
});
export const requestFailure = (errMsg) => ({
type: booksActionTypes.REQUEST_FAILURE,
payload: errMsg,
});
export const actionCreators = {
// "applicationUrl": "http://localhost:51374", http://erikswed.ddns.net:8965/api/BooksXml/getbooks/fromall/?title=dep&author=&genre=&price=
// "sslPort": 44378
requestBooks: (book) => async (dispatch, getState) => {
dispatch(requestStart());
dispatch(
setLogMessage(() => ({
message: "Starting books search..",
timestamp:
new Date().getHours() +
"-" +
new Date().getMinutes() +
"-" +
new Date().getSeconds(),
type: "connecting",
}))
);
var queryString = Object.keys(book)
.map((key) => {
return encodeURIComponent(key) + "=" + encodeURIComponent(book[key]);
})
.join("&");
var url =
"htftp://erikswed.ddns.net:8965/api/BooksXml/getbooks/fromall/?" +
queryString;
dispatch(
setLogMessage(() => ({
message: "Search url is: ",
timestamp:
new Date().getHours() +
"-" +
new Date().getMinutes() +
"-" +
new Date().getSeconds(),
type: "connecting",
}))
);
dispatch(
setLogMessage(() => ({
message: "Sdsadsasada: ",
timestamp:
new Date().getHours() +
"-" +
new Date().getMinutes() +
"-" +
new Date().getSeconds(),
type: "connecting",
}))
);
await fetch(url)
.then((res) => res.json())
.then((xml) => {
dispatch(requestSuccess(xml));
})
.catch((errMsg) => {
console.log(errMsg);
dispatch(requestFailure(errMsg));
fetch("books.xml")
.then((res) => res.text())
.then((xmlString) => getFromLocalDatabas(dispatch, xmlString, book))
.catch((err) => {
dispatch(requestFailure(errMsg));
});
});
},
};
function getFromLocalDatabas(dispatch, xmlFile, book) {
var parser = new window.DOMParser();
var xmlDoc = parser.parseFromString(xmlFile, "text/xml");
var books = xmlDoc.documentElement.childNodes;
var map = [];
for (var i = 0; i < books.length; i++) {
var author = books[i]
.getElementsByTagName("author")[0]
.childNodes[0].nodeValue.toLowerCase();
var title = books[i]
.getElementsByTagName("title")[0]
.childNodes[0].nodeValue.toLowerCase();
var genre = books[i]
.getElementsByTagName("genre")[0]
.childNodes[0].nodeValue.toLowerCase();
var price = books[i]
.getElementsByTagName("price")[0]
.childNodes[0].nodeValue.toLowerCase();
var publish_date = books[i]
.getElementsByTagName("publish_date")[0]
.childNodes[0].nodeValue.toLowerCase();
var description = books[i]
.getElementsByTagName("description")[0]
.childNodes[0].nodeValue.toLowerCase();
if (book.author && author.indexOf(book.author.toLowerCase()) >= 0) {
sendBackThisBook(map, books[i]);
}
if (book.title && title.indexOf(book.title.toLowerCase()) >= 0) {
sendBackThisBook(map, books[i]);
}
if (book.genre && genre.indexOf(book.genre.toLowerCase()) >= 0) {
sendBackThisBook(map, books[i]);
}
if (book.price && price.indexOf(book.price.toLowerCase()) >= 0) {
sendBackThisBook(map, books[i]);
}
if (
book.publish_date &&
publish_date.indexOf(book.publish_date.toLowerCase()) >= 0
) {
sendBackThisBook(map, books[i]);
}
if (
book.description &&
description.indexOf(book.description.toLowerCase()) >= 0
) {
sendBackThisBook(map, books[i]);
}
}
dispatch(requestSuccess(map));
}
function sendBackThisBook(map, book) {
var index = map.findIndex((x) => x.id == book.getAttribute("id"));
if (index != -1) {
console.log(`exist skipping `, book.getAttribute("id"));
return;
}
map.push({
id: book.getAttribute("id"),
title: book.getElementsByTagName("title")[0].childNodes[0].nodeValue,
author: book.getElementsByTagName("author")[0].childNodes[0].nodeValue,
genre: book.getElementsByTagName("genre")[0].childNodes[0].nodeValue,
price: book.getElementsByTagName("price")[0].childNodes[0].nodeValue,
publish_date: book.getElementsByTagName("publish_date")[0].childNodes[0]
.nodeValue,
description: book.getElementsByTagName("description")[0].childNodes[0]
.nodeValue,
});
}
import React, { useEffect, useState } from "react";
import { makeStyles } from "@material-ui/core/styles";
import { connect } from "react-redux";
import Table from "@material-ui/core/Table";
import TableBody from "@material-ui/core/TableBody";
import TableCell from "@material-ui/core/TableCell";
import TableRow from "@material-ui/core/TableRow";
import { Icon } from "@material-ui/core";
import {
CallMade,
CallReceived,
FiberManualRecord,
Error,
} from "@material-ui/icons";
function createData(message, timestamp, type) {
return { message, timestamp, type };
}
const rows = [];
const useStyles = makeStyles((theme) => ({
root: {
width: "100%",
},
icons: {
fontSize: 18,
},
connecting: {
color: "#11FF0C",
},
connected: {
color: "#11FF0C",
},
disconnecting: {
color: "#FF5050",
},
disconnected: {
color: "#FF5050",
},
error: {
color: "#FF5050",
},
request: {
// color: "#11FF0C"
},
response: {
// color: "#11FF0C"
},
}));
function Logger(props) {
const { v4: uuidv4 } = require("uuid");
const classes = useStyles();
const [theLog, addLog] = useState([]);
useEffect(() => {
if (typeof props.log === "function") {
const values = props.log();
addLog([
...theLog,
createData(values.message, values.timestamp, values.type),
]);
}
}, [props.log]);
function createData(message, timestamp, type) {
console.log("s");
return { message, timestamp, type };
}
return (
<div>
{props.showLog ? (
<div className={classes.root}>
<Table aria-labelledby="tableTitle" size="small">
<TableBody>
{theLog.map((row, index) => {
return (
<TableRow
key={uuidv4()}
hover
role="checkbox"
tabIndex={-1}
key={row.timestamp}
>
<TableCell padding="checkbox">
<Icon>
{row.type === "connecting" && (
<FiberManualRecord
className={`${classes.connecting} ${classes.icons}`}
/>
)}
{row.type === "connected" && (
<FiberManualRecord
className={`${classes.connected} ${classes.icons}`}
/>
)}
{row.type === "disconnecting" && (
<FiberManualRecord
className={`${classes.disconnecting} ${classes.icons}`}
/>
)}
{row.type === "disconnected" && (
<FiberManualRecord
className={`${classes.disconnected} ${classes.icons}`}
/>
)}
{row.type === "error" && (
<Error
className={`${classes.error} ${classes.icons}`}
/>
)}
{row.type === "request" && (
<CallMade
className={`${classes.request} ${classes.icons}`}
/>
)}
{row.type === "response" && (
<CallReceived
className={`${classes.response} ${classes.icons}`}
/>
)}
</Icon>
</TableCell>
<TableCell>{row.message}</TableCell>
<TableCell>{row.timestamp}</TableCell>
</TableRow>
);
})}
</TableBody>
</Table>
</div>
) : null}
</div>
);
}
function mapStateToProps(state) {
return {
log: state.reducer.log,
showLog: state.reducer.showLog,
};
}
export default connect(mapStateToProps, null)(Logger);
从“/books.types”导入{booksActionTypes};
导出常量showLog=()=>({
类型:booksActionTypes.SHOWLOG,
});
导出常量setLogMessage=(日志)=>({
类型:booksActionTypes.LOG_消息,
有效载荷:日志,
});
导出常量clearPosts=()=>({
类型:booksActionTypes.CLEAR_POSTS,
});
导出常量requestStart=()=>({
类型:booksActionTypes.REQUEST\u START,
});
导出const requestSuccess=(booksList)=>({
类型:booksActionTypes.REQUEST\u SUCCESS,
有效载荷:图书列表,
});
导出常量请求失败=(errMsg)=>({
类型:booksActionTypes.REQUEST\u失败,
有效载荷:errMsg,
});
导出常量actionCreators={
//“应用程序URL”:http://localhost:51374", http://erikswed.ddns.net:8965/api/BooksXml/getbooks/fromall/?title=dep&author=&genre=&price=
//“sslPort”:44378
requestBooks:(book)=>async(dispatch,getState)=>{
分派(requestStart());
派遣(
setLogMessage(()=>({
消息:“开始图书搜索…”,
时间戳:
新建日期().getHours()+
"-" +
新建日期().getMinutes()+
"-" +
新建日期().getSeconds(),
类型:“正在连接”,
}))
);
var queryString=Object.keys(书本)
.map((键)=>{
返回encodeURIComponent(key)+“=”+encodeURIComponent(book[key]);
})
.加入(“&”);
变量url=
"htftp://erikswed.ddns.net:8965/api/BooksXml/getbooks/fromall/?" +
询问;
派遣(
setLogMessage(()=>({
消息:“搜索url为:”,
时间戳:
新建日期().getHours()+
"-" +
新建日期().getMinutes()+
"-" +
新建日期().getSeconds(),
类型:“正在连接”,
}))
);
派遣(
setLogMessage(()=>({
信息:“Sdsadsasada:”,
时间戳:
新建日期().getHours()+
"-" +
新建日期().getMinutes()+
"-" +
新建日期().getSeconds(),
类型:“正在连接”,
}))
);
等待获取(url)
.然后((res)=>res.json())
。然后((xml)=>{
调度(requestSuccess(xml));
})
.catch((errMsg)=>{
console.log(errMsg);
调度(请求失败(errMsg));
获取(“books.xml”)
.然后((res)=>res.text())
.then((xmlString)=>getFromLocalDatabase(dispatch,xmlString,book))
.catch((错误)=>{
调度(请求失败(errMsg));
});
});
},
};
函数getFromLocalDatabase(分派、xmlFile、book){
var parser=new window.DOMParser();
var xmlDoc=parser.parseFromString(xmlFile,“text/xml”);
var books=xmlDoc.documentElement.childNodes;
var-map=[];
for(var i=0;i=0){
发回本书(地图、书籍[i]);
}
if(book.title&&title.indexOf(book.title.toLowerCase())>=0){
发回本书(地图、书籍[i]);
}
if(book.genre&&genre.indexOf(book.genre.toLowerCase())>=0){
发回本书(地图、书籍[i]);
}
if(book.price&&price.indexOf(book.price.toLowerCase())>=0){
发回本书(地图、书籍[i]);
}
如果(
出版日期&&
publish_date.indexOf(book.publish_date.toLowerCase())>=0
) {
发回本书(地图、书籍[i]);
}
如果(
书名&&
description.indexOf(book.description.toLowerCase())>=0
) {
发回本书(地图、书籍[i]);
}
}
调度(请求成功(map));
}
函数sendBackThisBook(地图、书本){
var index=map.findIndex((x)=>x.id==book.getAttribute(“id”);
如果(索引!=-1){
log(`existskipping`,book.getAttribute(“id”);
返回;
}
地图推送({
id:book.getAttribute(“id”),
标题:book.getElementsByTagName(“标题”)[0]。子节点[0]。节点值,
作者:book.getElementsByTagName(“作者”)[0]。子节点[0]。节点值,
类型:book.getElementsByTagName(“类型”)[0]。子节点[0]。节点值,
价格:book.getElementsByTagName(“价格”)[0]。childNodes[0]。nodeValue,
发布日期:book.getElementsByTagName(“发布日期”)[0]。子节点[0]
诺德瓦卢先生,
描述:book.getElementsByTagName(“描述”)[0].childNodes[0]
诺德瓦卢先生,
});
}
这是接收Redux存储状态的类:
import { booksActionTypes } from "./books.types";
export const showLog = () => ({
type: booksActionTypes.SHOWLOG,
});
export const setLogMessage = (log) => ({
type: booksActionTypes.LOG_MESSAGE,
payload: log,
});
export const clearPosts = () => ({
type: booksActionTypes.CLEAR_POSTS,
});
export const requestStart = () => ({
type: booksActionTypes.REQUEST_START,
});
export const requestSuccess = (booksList) => ({
type: booksActionTypes.REQUEST_SUCCESS,
payload: booksList,
});
export const requestFailure = (errMsg) => ({
type: booksActionTypes.REQUEST_FAILURE,
payload: errMsg,
});
export const actionCreators = {
// "applicationUrl": "http://localhost:51374", http://erikswed.ddns.net:8965/api/BooksXml/getbooks/fromall/?title=dep&author=&genre=&price=
// "sslPort": 44378
requestBooks: (book) => async (dispatch, getState) => {
dispatch(requestStart());
dispatch(
setLogMessage(() => ({
message: "Starting books search..",
timestamp:
new Date().getHours() +
"-" +
new Date().getMinutes() +
"-" +
new Date().getSeconds(),
type: "connecting",
}))
);
var queryString = Object.keys(book)
.map((key) => {
return encodeURIComponent(key) + "=" + encodeURIComponent(book[key]);
})
.join("&");
var url =
"htftp://erikswed.ddns.net:8965/api/BooksXml/getbooks/fromall/?" +
queryString;
dispatch(
setLogMessage(() => ({
message: "Search url is: ",
timestamp:
new Date().getHours() +
"-" +
new Date().getMinutes() +
"-" +
new Date().getSeconds(),
type: "connecting",
}))
);
dispatch(
setLogMessage(() => ({
message: "Sdsadsasada: ",
timestamp:
new Date().getHours() +
"-" +
new Date().getMinutes() +
"-" +
new Date().getSeconds(),
type: "connecting",
}))
);
await fetch(url)
.then((res) => res.json())
.then((xml) => {
dispatch(requestSuccess(xml));
})
.catch((errMsg) => {
console.log(errMsg);
dispatch(requestFailure(errMsg));
fetch("books.xml")
.then((res) => res.text())
.then((xmlString) => getFromLocalDatabas(dispatch, xmlString, book))
.catch((err) => {
dispatch(requestFailure(errMsg));
});
});
},
};
function getFromLocalDatabas(dispatch, xmlFile, book) {
var parser = new window.DOMParser();
var xmlDoc = parser.parseFromString(xmlFile, "text/xml");
var books = xmlDoc.documentElement.childNodes;
var map = [];
for (var i = 0; i < books.length; i++) {
var author = books[i]
.getElementsByTagName("author")[0]
.childNodes[0].nodeValue.toLowerCase();
var title = books[i]
.getElementsByTagName("title")[0]
.childNodes[0].nodeValue.toLowerCase();
var genre = books[i]
.getElementsByTagName("genre")[0]
.childNodes[0].nodeValue.toLowerCase();
var price = books[i]
.getElementsByTagName("price")[0]
.childNodes[0].nodeValue.toLowerCase();
var publish_date = books[i]
.getElementsByTagName("publish_date")[0]
.childNodes[0].nodeValue.toLowerCase();
var description = books[i]
.getElementsByTagName("description")[0]
.childNodes[0].nodeValue.toLowerCase();
if (book.author && author.indexOf(book.author.toLowerCase()) >= 0) {
sendBackThisBook(map, books[i]);
}
if (book.title && title.indexOf(book.title.toLowerCase()) >= 0) {
sendBackThisBook(map, books[i]);
}
if (book.genre && genre.indexOf(book.genre.toLowerCase()) >= 0) {
sendBackThisBook(map, books[i]);
}
if (book.price && price.indexOf(book.price.toLowerCase()) >= 0) {
sendBackThisBook(map, books[i]);
}
if (
book.publish_date &&
publish_date.indexOf(book.publish_date.toLowerCase()) >= 0
) {
sendBackThisBook(map, books[i]);
}
if (
book.description &&
description.indexOf(book.description.toLowerCase()) >= 0
) {
sendBackThisBook(map, books[i]);
}
}
dispatch(requestSuccess(map));
}
function sendBackThisBook(map, book) {
var index = map.findIndex((x) => x.id == book.getAttribute("id"));
if (index != -1) {
console.log(`exist skipping `, book.getAttribute("id"));
return;
}
map.push({
id: book.getAttribute("id"),
title: book.getElementsByTagName("title")[0].childNodes[0].nodeValue,
author: book.getElementsByTagName("author")[0].childNodes[0].nodeValue,
genre: book.getElementsByTagName("genre")[0].childNodes[0].nodeValue,
price: book.getElementsByTagName("price")[0].childNodes[0].nodeValue,
publish_date: book.getElementsByTagName("publish_date")[0].childNodes[0]
.nodeValue,
description: book.getElementsByTagName("description")[0].childNodes[0]
.nodeValue,
});
}
import React, { useEffect, useState } from "react";
import { makeStyles } from "@material-ui/core/styles";
import { connect } from "react-redux";
import Table from "@material-ui/core/Table";
import TableBody from "@material-ui/core/TableBody";
import TableCell from "@material-ui/core/TableCell";
import TableRow from "@material-ui/core/TableRow";
import { Icon } from "@material-ui/core";
import {
CallMade,
CallReceived,
FiberManualRecord,
Error,
} from "@material-ui/icons";
function createData(message, timestamp, type) {
return { message, timestamp, type };
}
const rows = [];
const useStyles = makeStyles((theme) => ({
root: {
width: "100%",
},
icons: {
fontSize: 18,
},
connecting: {
color: "#11FF0C",
},
connected: {
color: "#11FF0C",
},
disconnecting: {
color: "#FF5050",
},
disconnected: {
color: "#FF5050",
},
error: {
color: "#FF5050",
},
request: {
// color: "#11FF0C"
},
response: {
// color: "#11FF0C"
},
}));
function Logger(props) {
const { v4: uuidv4 } = require("uuid");
const classes = useStyles();
const [theLog, addLog] = useState([]);
useEffect(() => {
if (typeof props.log === "function") {
const values = props.log();
addLog([
...theLog,
createData(values.message, values.timestamp, values.type),
]);
}
}, [props.log]);
function createData(message, timestamp, type) {
console.log("s");
return { message, timestamp, type };
}
return (
<div>
{props.showLog ? (
<div className={classes.root}>
<Table aria-labelledby="tableTitle" size="small">
<TableBody>
{theLog.map((row, index) => {
return (
<TableRow
key={uuidv4()}
hover
role="checkbox"
tabIndex={-1}
key={row.timestamp}
>
<TableCell padding="checkbox">
<Icon>
{row.type === "connecting" && (
<FiberManualRecord
className={`${classes.connecting} ${classes.icons}`}
/>
)}
{row.type === "connected" && (
<FiberManualRecord
className={`${classes.connected} ${classes.icons}`}
/>
)}
{row.type === "disconnecting" && (
<FiberManualRecord
className={`${classes.disconnecting} ${classes.icons}`}
/>
)}
{row.type === "disconnected" && (
<FiberManualRecord
className={`${classes.disconnected} ${classes.icons}`}
/>
)}
{row.type === "error" && (
<Error
className={`${classes.error} ${classes.icons}`}
/>
)}
{row.type === "request" && (
<CallMade
className={`${classes.request} ${classes.icons}`}
/>
)}
{row.type === "response" && (
<CallReceived
className={`${classes.response} ${classes.icons}`}
/>
)}
</Icon>
</TableCell>
<TableCell>{row.message}</TableCell>
<TableCell>{row.timestamp}</TableCell>
</TableRow>
);
})}
</TableBody>
</Table>
</div>
) : null}
</div>
);
}
function mapStateToProps(state) {
return {
log: state.reducer.log,
showLog: state.reducer.showLog,
};
}
export default connect(mapStateToProps, null)(Logger);
import React,{useffect,useState}来自“React”;
从“@material ui/core/styles”导入{makeStyles}”;
从“react redux”导入{connect};
从“@物料界面/核心/表格”导入表格;
从“@material ui/core/TableBody”导入表体;
导入表单元格