【发布时间】:2022-08-13 23:24:15
【问题描述】:
较新的反应。我在具有输入文本框的 ReactTable 中有此列。我知道更改状态是重新渲染表单,只是不确定如何防止这种情况。感谢任何指导!
<ReactTable
key={googlecampaigndata?.length}
data={googlecampaigndata}
loading={googlecampaignloading}
sortable={false}
filterable={false}
columns={[
{
Header: \"Account Name\",
accessor: \"customer_name\"
},
{
Header: \"Campaign Name\",
accessor: \"campaign_name\"
},
{
Header: \"Campaign Type\",
accessor: \"campaign_type\"
},
{
Header: \"Status\",
accessor: \"status\"
},
{
Header: \"Monthly Budget\",
accessor: \"monthly_budget\"
},
{
Header: \"Update Monthly Budget\",
accessor: \"update_monthly_budget\",
Cell: ({ original }) => {
return (
<form
onSubmit={e => {
e.preventDefault();
if(submissionData !== {} && submitGoogleCampaignMonthlyBudgetForm()){
refetch();
}
}
}
>
<input
id={`monthly_budget${original.id}`}
type=\"text\"
maxLength=\"12\"
size=\"8\"
style={{ float: \"left\" }}
onChange = {updateFieldHandler(\"monthly_budget\", original.id)}
inputprops={{
type: \"string\",
required: true,
value: original[\'monthly_budget\'] ? original[\'monthly_budget\'] : \"\"
}}
/><Button
color=\"primary\"
type=\"submit\"
style={{ float: \"right\" }}
>
Submit
</Button>
</form>
);
},
},
{
Header: \"Cycle Start Date\",
accessor: \"date\"
}
]}
defaultPageSize={Math.min(pageSize, googlecampaigndata?.length || 2)}
showPaginationTop
showPaginationBottom={false}
onPageSizeChange={ps => setPageSize(ps)}
className=\"-striped -highlight\"
/>
#编辑 我尝试从 MyAccounts 外部返回我的输入字段,但在输入时我仍然无法专注于输入。下面是我更新的更多代码。
import React, { useState, useContext, useEffect } from \"react\";
import { useQuery, useMutation } from \"@apollo/react-hooks\";
import { intersection, omit } from \"lodash\";
// @material-ui/core components
import { makeStyles } from \"@material-ui/core/styles\";
// @material-ui/icons
import Assignment from \"@material-ui/icons/Assignment\";
// core components
import GridContainer from \"components/Grid/GridContainer\";
import GridItem from \"components/Grid/GridItem\";
import Card from \"components/Card/Card\";
import CardBody from \"components/Card/CardBody\";
import CardIcon from \"components/Card/CardIcon\";
import CardHeader from \"components/Card/CardHeader\";
import ReactTable from \"components/CustomReactTable\";
import Button from \"components/CustomButtons/Button\";
import { cardTitle } from \"assets/jss/material-dashboard-pro-react\";
import { SUBMIT_GOOGLE_CAMPAIGN_MONTHLY_BUDGET_FORM } from \"queries/formSubmission\";
import { LIST_BUDGETS } from \"queries/budget\";
import { GET_GOOGLE_CAMPAIGNS } from \"queries/budget\";
import { Context } from \"redux/store\";
const styles = {
cardIconTitle: {
...cardTitle,
marginTop: \"15px\",
marginBottom: \"0px\"
}
};
const useStyles = makeStyles(styles);
const GoogleCampaignMonthlyBudgetInput = ({ original, setSubmissionData, submissionData, state, onChange }) => {
return (
<input
id={`monthly_budget${original.id}`}
type=\"text\"
maxLength=\"12\"
size=\"8\"
style={{ float: \"left\" }}
key={original.id}
onChange={ onChange }
value={submissionData.id === original.id ? submissionData.monthly_budget : original.monthly_budget ? (original.monthly_budget / (1 - (state.customers?.selected?.margin / 100.0))) / 1000000 : \"\"}
inputprops={{
type: \"string\",
required: true,
}}
/>
);
}
const MyAccounts = () => {
const [state] = useContext(Context);
const [pageSize, setPageSize] = useState(20);
const customer_id = state.customers?.selected?.id;
const [submissionData, setSubmissionData] = useState({});
let { loading, data } = useQuery(LIST_BUDGETS);
let { loading: googlecampaignloading, data: googlecampaigndata, refetch } = useQuery(GET_GOOGLE_CAMPAIGNS);
googlecampaigndata = googlecampaigndata?.getGoogleCampaigns || [];
data = data?.listBudgets || [];
data = data.map((row, index) => {
let customer_name = \"\";
let product_line = \"\";
if (
index % pageSize === 0 ||
row.customer_name !== data[index - 1].customer_name
) {
customer_name = row.customer_name;
}
if (
index % pageSize === 0 ||
row.product_line !== data[index - 1].product_line
) {
product_line = row.product_line;
}
return {
...row,
customer_name,
product_line
};
});
const [submitGoogleCampaignMonthlyBudgetForm, { loading: submitting }] = useMutation(
SUBMIT_GOOGLE_CAMPAIGN_MONTHLY_BUDGET_FORM,
{
variables: {
customerId: customer_id,
data: submissionData
},
onCompleted: () => {
return true;
}
}
);
const classes = useStyles();
return (
<GridContainer>
<GridItem xs={12}>
<Card>
<CardHeader color=\"trackedKeywords\" icon>
<CardIcon>
<Assignment />
</CardIcon>
<h4 className={classes.cardIconTitle}>Google Campaigns</h4>
</CardHeader>
<CardBody>
<ReactTable
key={googlecampaigndata?.length}
data={googlecampaigndata}
loading={googlecampaignloading}
sortable={false}
filterable={false}
columns={[
{
Header: \"Monthly Budget\",
accessor: \"monthly_budget\",
Cell: ({ original }) => {
return (
<div>{original.monthly_budget ? (original.monthly_budget / (1 - (state.customers?.selected?.margin / 100.0))) / 1000000 : \"\"}</div>
);
},
},
{
Header: \"Update Monthly Budget\",
accessor: \"update_monthly_budget\",
Cell: ({ original }) => {
return (
<form
onSubmit={e => {
e.preventDefault();
if(submissionData !== {} && submitGoogleCampaignMonthlyBudgetForm()){
refetch();
}
}
}
>
<GoogleCampaignMonthlyBudgetInput original={original} onChange={e => setSubmissionData({...submissionData, \"monthly_budget\": parseFloat(e.target.value), \"id\": original.id })} setSubmissionData={setSubmissionData} submissionData={submissionData} state={state} key={original.id} />
<Button
color=\"primary\"
type=\"submit\"
style={{ float: \"right\" }}
>
Submit
</Button>
</form>
);
},
},
{
Header: \"Cycle Start Date\",
accessor: \"date\"
}
]}
defaultPageSize={Math.min(pageSize, googlecampaigndata?.length || 2)}
showPaginationTop
showPaginationBottom={false}
onPageSizeChange={ps => setPageSize(ps)}
className=\"-striped -highlight\"
/>
</CardBody>
</Card>
</GridItem>
</GridContainer>
);
};
export default MyAccounts;
编辑 2:我在 inwerpsel 的帮助下得到的代码!
{
Header: \"Monthly Budget\",
accessor: \"monthly_budget\",
Cell: ({ original }) => {
return (
<div>{submissionData.id === original.id ? submissionData.monthly_budget : original.monthly_budget ? (original.monthly_budget / (1 - (state.customers?.selected?.margin / 100.0))) / 1000000 : \"\"}</div>
);
},
},
{
Header: \"Update Monthly Budget\",
accessor: \"update_monthly_budget\",
Cell: ({ original }) => {
const [textInput, setTextInput] = useState(null);
const [submitGoogleCampaignMonthlyBudgetForm, { loading: submitting }] = useMutation(
SUBMIT_GOOGLE_CAMPAIGN_MONTHLY_BUDGET_FORM,
{
variables: {
customerId: customer_id,
data: submissionData
},
onCompleted: () => {
refetch();
return true;
}
}
);
return (
<form
key={\"form\"+original.id}
onSubmit={e => {
e.preventDefault();
if(Number.isNaN(textInput) || textInput === \"\" || textInput === null){
setSubmissionData({});
return;
}
submissionData[\"monthly_budget\"] = parseFloat(textInput);
submissionData[\"id\"] = original.id;
if(submissionData !== {} && submitGoogleCampaignMonthlyBudgetForm()){
refetch();
setSubmissionData({});
}
}
}
>
<input
id={`monthly_budget${original.id}`}
type=\"text\"
maxLength=\"12\"
size=\"8\"
style={{ float: \"left\" }}
key={original.id}
onChange = {event => { setTextInput(event.target.value) }}
defaultValue={submissionData.id === original.id ? submissionData.monthly_budget : original.monthly_budget ? (original.monthly_budget / (1 - (state.customers?.selected?.margin / 100.0))) / 1000000 : \"\"}
inutprops={{
type: \"string\",
required: true,
}}
/>
<Button
color=\"primary\"
type=\"submit\"
style={{ float: \"right\" }}
>
Submit
</Button>
</form>
);
},
},
-
我的猜测是这条线
value={submissionData.id === original.id ? submissionData.monthly_budget : original.monthly_budget ? (original.monthly_budget / (1 - (state.customers?.selected?.margin / 100.0))) / 1000000 : \"\"}在你的上下文state和你的submissionData状态之间创建一个循环依赖。我相信您可以使用useCallback或useMemo来避免这种情况。您能否在 Repl.it 上创建一个复制品,以便我们对其进行调整?
标签: reactjs input onchange react-table