当 redux 状态改变时改变 useState
change useState when redux state change
我有一个带有 useState 挂钩的功能组件。它的值来自我的 redux store,我想在每次调度一个动作时用 are store 状态更新状态。
现在我已经硬编码了一个 useState 开头的数组。我希望能够通过 redux 将新元素推送到数组中,并重新呈现新内容。
查看下面的代码:
import React, { useState } from "react";
import "./style.scss";
import { FormEquation } from "../calc/interfaces/form";
import { FlowrateCalc } from "../calc/calculators/FlowrateCalc";
import { useSelector } from "react-redux";
import { RootState } from "../state/reducers";
import { ValveKvsCalc } from "../calc/calculators/ValveKvsCalc";
function Calculator() {
const state = useSelector((state: RootState) => state.calc);
// const state = [
// {
// ...FlowrateCalc,
// priorityList: FlowrateCalc.inputs.map((input) => input.name),
// },
// {
// ...ValveKvsCalc,
// priorityList: ValveKvsCalc.inputs.map((input) => input.name),
// },
// ];
// Usestate is run once after render and never again. How do I update this state whenever new content arrived from "useSelector"??
const [formsEQ, setformsEQ] = useState<FormEquation[]>([...state]);
const inputsHandler = (e: React.ChangeEvent<HTMLInputElement>) => {
// Copy form and get index of affected form
const formCopy = formsEQ.slice();
const [formName, inputFieldName] = e.target.name.split("-");
const formIndex = formsEQ.findIndex((formEQ) => formEQ.name === formName);
if (formIndex === -1) return;
// if anything other than a number or dot inputted, then return
// meTODO: if added number then trying to delete all numbers will stop!
const isInputNum = e.target.value.match(/[0-9]*\.?[0-9]*/);
if (!isInputNum || isInputNum[0] === "") return;
// Update priority list to calculate the last updated input
formCopy[formIndex].priorityList = formCopy[formIndex].priorityList.sort((a, b) => {
if (a === inputFieldName) return 1;
if (b === inputFieldName) return -1;
else return 0;
});
// Update selected input field
formCopy[formIndex].inputs = formCopy[formIndex].inputs.map((input) => {
if (input.name === inputFieldName) {
input.value = e.target.value;
}
return input;
});
// If more than two inputs empty do not calculate
const emptyInputs = formCopy[formIndex].inputs.reduce(
(acc, nV) => (nV.value === "" ? (acc += 1) : acc),
0
);
// Calculate the last edited input field
formCopy[formIndex].inputs = formCopy[formIndex].inputs.map((input) => {
if (input.name === formCopy[formIndex].priorityList[0] && emptyInputs <= 1) {
const calculatedValue = formCopy[formIndex].calculate(formCopy[formIndex].priorityList[0]);
input.value = calculatedValue;
}
return input;
});
// Final set hook, now with calculated value
setformsEQ([...formCopy]);
};
const formInputs = formsEQ.map((formEQ) => {
return (
<form className="form" key={formEQ.name}>
{formEQ.inputs?.map((formInput) => {
return (
<div className="form__input" key={formInput.name}>
<label>{formInput.label}: </label>
<input
name={`${formEQ.name}-${formInput.name}`}
onChange={inputsHandler}
placeholder={`${formInput.label} (${formInput.selectedUnit})`}
value={formInput.value}
/>
</div>
);
})}
</form>
);
});
return <div>{formInputs}</div>;
}
export default Calculator;
对于任何正在阅读本文并且像我一样是 react 新手的人。
我的解决方案是使用 useEffect 钩子;并且每当 useSelector 更新状态常量时,useEffect 钩子将使用 useState set 函数来更新状态。
查看下面添加的解决我的问题的代码:
useEffect(() => {
setformsEQ([...state])
}, [state])
我有一个带有 useState 挂钩的功能组件。它的值来自我的 redux store,我想在每次调度一个动作时用 are store 状态更新状态。
现在我已经硬编码了一个 useState 开头的数组。我希望能够通过 redux 将新元素推送到数组中,并重新呈现新内容。
查看下面的代码:
import React, { useState } from "react";
import "./style.scss";
import { FormEquation } from "../calc/interfaces/form";
import { FlowrateCalc } from "../calc/calculators/FlowrateCalc";
import { useSelector } from "react-redux";
import { RootState } from "../state/reducers";
import { ValveKvsCalc } from "../calc/calculators/ValveKvsCalc";
function Calculator() {
const state = useSelector((state: RootState) => state.calc);
// const state = [
// {
// ...FlowrateCalc,
// priorityList: FlowrateCalc.inputs.map((input) => input.name),
// },
// {
// ...ValveKvsCalc,
// priorityList: ValveKvsCalc.inputs.map((input) => input.name),
// },
// ];
// Usestate is run once after render and never again. How do I update this state whenever new content arrived from "useSelector"??
const [formsEQ, setformsEQ] = useState<FormEquation[]>([...state]);
const inputsHandler = (e: React.ChangeEvent<HTMLInputElement>) => {
// Copy form and get index of affected form
const formCopy = formsEQ.slice();
const [formName, inputFieldName] = e.target.name.split("-");
const formIndex = formsEQ.findIndex((formEQ) => formEQ.name === formName);
if (formIndex === -1) return;
// if anything other than a number or dot inputted, then return
// meTODO: if added number then trying to delete all numbers will stop!
const isInputNum = e.target.value.match(/[0-9]*\.?[0-9]*/);
if (!isInputNum || isInputNum[0] === "") return;
// Update priority list to calculate the last updated input
formCopy[formIndex].priorityList = formCopy[formIndex].priorityList.sort((a, b) => {
if (a === inputFieldName) return 1;
if (b === inputFieldName) return -1;
else return 0;
});
// Update selected input field
formCopy[formIndex].inputs = formCopy[formIndex].inputs.map((input) => {
if (input.name === inputFieldName) {
input.value = e.target.value;
}
return input;
});
// If more than two inputs empty do not calculate
const emptyInputs = formCopy[formIndex].inputs.reduce(
(acc, nV) => (nV.value === "" ? (acc += 1) : acc),
0
);
// Calculate the last edited input field
formCopy[formIndex].inputs = formCopy[formIndex].inputs.map((input) => {
if (input.name === formCopy[formIndex].priorityList[0] && emptyInputs <= 1) {
const calculatedValue = formCopy[formIndex].calculate(formCopy[formIndex].priorityList[0]);
input.value = calculatedValue;
}
return input;
});
// Final set hook, now with calculated value
setformsEQ([...formCopy]);
};
const formInputs = formsEQ.map((formEQ) => {
return (
<form className="form" key={formEQ.name}>
{formEQ.inputs?.map((formInput) => {
return (
<div className="form__input" key={formInput.name}>
<label>{formInput.label}: </label>
<input
name={`${formEQ.name}-${formInput.name}`}
onChange={inputsHandler}
placeholder={`${formInput.label} (${formInput.selectedUnit})`}
value={formInput.value}
/>
</div>
);
})}
</form>
);
});
return <div>{formInputs}</div>;
}
export default Calculator;
对于任何正在阅读本文并且像我一样是 react 新手的人。 我的解决方案是使用 useEffect 钩子;并且每当 useSelector 更新状态常量时,useEffect 钩子将使用 useState set 函数来更新状态。
查看下面添加的解决我的问题的代码:
useEffect(() => {
setformsEQ([...state])
}, [state])