我目前正在开发一个 React 应用程序,并尝试检测达到特定输入值长度所需的时间。
它是一个受控输入,通过 redux 操作和减速器存储和设置值。
我想当输入值为
!== ""
时开始计时,并在.length
等于13时停止计时。
此外,在应用程序逻辑中,如果到达
.length === 13
所需的时间类似于100ms
(+或-),则意味着应用程序用户使用了条形码扫描仪,否则,他用键盘输入了条形码.
我尝试使用带有
new Date()
的变量来获取时间差异,但是 render()
逻辑阻止了对经过时间计数的维护...
知道如何实现我的目标吗?
我在下面留下了组件代码, 预先感谢您!
import React from "react";
import StoreInput from "../StoreInput/index";
import { connect } from "react-redux";
import "./index.scss";
import { setStoreInputFieldValue } from "../../actions/store.actions";
import { addArticleToStore } from "../../actions/articles.actions";
type ScanSetProps = {
// Redux State
storeInputFieldValue?: any;
// Redux Actions
setStoreInputFieldValue?: any;
addArticleToStore?: any;
};
class ScanSet extends React.Component<ScanSetProps> {
handleScanSet = (event) => {
const { setStoreInputFieldValue } = this.props;
setStoreInputFieldValue(event.target.value);
};
// Component render
render() {
const { storeInputFieldValue, addArticleToStore } = this.props;
return (
<div className="ScanSet">
<StoreInput
idStoreInput={"scanSetInput"}
typeStoreInput={"number"}
placeholderStoreInput={
"Scannez le code barre ou saisissez le code EAN"
}
storeInputFillMethod={this.handleScanSet}
/>
<button
id="scanSetButton"
className={
storeInputFieldValue.length === 13
? "enabledButton"
: "disabledButton"
}
onClick={() => addArticleToStore(storeInputFieldValue)}
>
Ajouter
</button>
</div>
);
}
}
const mapStateToProps = (state) => ({
storeInputFieldValue: state.store.storeInputFieldValue,
});
const mapDispatchToProps = (dispatch) => ({
setStoreInputFieldValue: (input_value) =>
dispatch(setStoreInputFieldValue(input_value)),
addArticleToStore: (article_ean) => dispatch(addArticleToStore(article_ean)),
});
export default connect(mapStateToProps, mapDispatchToProps)(ScanSet);
我建议使用状态。
当输入!== "":
this.setState((state) => {...state, startTime: new Date().getTime()});
当 value.length === 13 时:
this.setState((state) => {...state, endTime: new Date().getTime()});
然后你可以用另一部分来解释差异(endTime - startTime)
因为您正在使用
redux
(如果您有一个切片可以解决此问题)。您可以简单地分派两个操作setStartTime, setEndTime
并让reducer处理上面的逻辑。
Urmzd 的答案是一个很好的方法,它解决了我的问题,并且每次
"SET_END_TIME"
操作被触发到 getTimeDiff
并启动进一步的逻辑时,也使用了 Redux Saga 库。这是代码现在的样子:
import StoreInput from "../StoreInput/index";
import { connect } from "react-redux";
import "./index.scss";
import {
setStoreInputFieldValue,
setStartTime,
setEndTime,
resetTimeDiff,
} from "../../actions/store.actions";
import { handleInputEan } from "../../actions/articles.actions";
type ScanSetProps = {
// Redux State
storeInputFieldValue?: any;
// Redux Actions
setStoreInputFieldValue?: any;
handleInputEan?: any;
setStartTime?: any;
setEndTime?: any;
resetTimeDiff?: any;
};
class ScanSet extends React.Component<ScanSetProps> {
handleScanSet = (event) => {
const {
setStoreInputFieldValue,
storeInputFieldValue,
setStartTime,
setEndTime,
resetTimeDiff,
} = this.props;
setStoreInputFieldValue(event.target.value);
if (storeInputFieldValue.length + 1 === 1) {
setStartTime();
} else if (storeInputFieldValue.length + 1 === 13) {
setEndTime();
} else if (storeInputFieldValue.length - 13 === 0) {
resetTimeDiff();
}
};
// Component render
render() {
const { storeInputFieldValue, handleInputEan } = this.props;
return (
<div className="ScanSet">
<StoreInput
idStoreInput={"scanSetInput"}
typeStoreInput={"number"}
placeholderStoreInput={
"Scannez le code barre ou saisissez le code EAN"
}
storeInputFillMethod={this.handleScanSet}
/>
<button
id="scanSetButton"
className={
storeInputFieldValue.length === 13
? "enabledButton"
: "disabledButton"
}
onClick={() => handleInputEan()}
>
Ajouter
</button>
</div>
);
}
}
const mapStateToProps = (state) => ({
storeInputFieldValue: state.store.storeInputFieldValue,
timeDiff: state.store.timeDiff,
});
const mapDispatchToProps = (dispatch) => ({
setStartTime: () => dispatch(setStartTime()),
setEndTime: () => dispatch(setEndTime()),
resetTimeDiff: () => dispatch(resetTimeDiff()),
setStoreInputFieldValue: (input_value) =>
dispatch(setStoreInputFieldValue(input_value)),
handleInputEan: () => dispatch(handleInputEan()),
});
export default connect(mapStateToProps, mapDispatchToProps)(ScanSet);
import * as storeConst from "../const/store.const";
export const setStartTime = () => ({
type: storeConst.SET_START_TIME,
payload: new Date().getTime(),
});
export const setEndTime = () => ({
type: storeConst.SET_END_TIME,
payload: new Date().getTime(),
});
export const getTimeDiff = () => ({
type: storeConst.GET_TIME_DIFF,
});
export const resetTimeDiff = () => ({
type: storeConst.RESET_TIME_DIFF,
});
import * as storeConst from "../const/store.const";
const initState = {
startTime: null,
endTime: null,
timeDiff: null,
};
const store = (state = initState, action) => {
switch (action.type) {
case storeConst.SET_START_TIME:
return { ...state, startTime: action.payload };
case storeConst.SET_END_TIME:
return { ...state, endTime: action.payload };
case storeConst.GET_TIME_DIFF:
return { ...state, timeDiff: state.endTime - state.startTime };
case storeConst.RESET_TIME_DIFF:
return { ...state, timeDiff: null };
default:
return state;
}
};
export default store;
import { put } from "redux-saga/effects";
import { store } from "../store";
import {
getTimeDiff,
resetTimeDiff,
} from "../actions/store.actions";
import {
handleInputEan,
} from "../actions/articles.actions";
export function* getTimeDiffLogic() {
yield put(getTimeDiff());
const timeDiff = yield store.getState().store.timeDiff;
if (timeDiff < 250) {
yield put(handleInputEan());
yield put(resetTimeDiff());
}
}
希望这能帮助像这样的人,这对我帮助很大!