Material-UI 和 Redux-form,重新渲染点击 select 的选项,如何防止?
Material-UI and Redux-form, re renders options clicked on select, how to prevent it?
所以我的问题是我正在动态呈现选项,当我单击 select 或组件重新呈现和更改选项的选项时,我需要单击两次才能 select select 中的一个选项。它正在重新渲染,因为它重新 运行 函数,我应该只将值 true/false 存储在反应钩子中并在第一个 运行 上更改它,这样它就不会重新 - 运行函数?
这是我的代码
这是创建选项的函数
渲染选项函数
const renderOptions = () => {
const days = [];
function dateWithMonthsDelay(months) {
const date = new Date();
date.setDate(date.getDate() + months);
return date;
}
let i = 0;
for (let d = new Date(); d <= dateWithMonthsDelay(7); d.setDate(d.getDate() + 1)) {
if (isAuthenticated && user) {
const u = user.name.match(/\d/g);
if (u) {
const us = user.name.match(/\d/g).join('');
if (new Date(d).getDay() === 1
&& (us === '25'
|| us === '26'
|| us === '27'
|| us === '3')) {
days.push(new Date(d));
} else if (new Date(d).getDay() === 3 && (
us === '24'
|| us === '28'
|| us === '22'
|| us === '8'
|| us === '9'
|| us === '14'
)) {
days.push(new Date(d));
} else if ((new Date(d).getDay() === 2 || new Date(d).getDay() === 5) && (
us === '17'
|| us === '21'
|| us === '7'
|| us === '2'
|| us === '4'
|| us === '18'
|| us === '20'
|| us === '23'
|| us === '10'
|| us === '12'
|| us === '16'
|| us === '5'
|| us === '29'
|| us === '30'
|| us === '11'
|| us === '19'
)) {
days.push(new Date(d));
}
}
}
}
return days.map((d) => (
<>
{i === 0 ? (<option aria-label="None" value="" />) : null}
{i += 1}
<option value={d}>
{moment(d).format('dddd - Do MMMM YYYY')}
</option>
</>
));
};
这是表单组件return
<Header>
<Container component="main" maxWidth="md">
<div className={classes.paper}>
<Typography component="h1" variant="h5">
GOLD
</Typography>
<form className={classes.form} onSubmit={handleSubmit(onSubmit)} noValidate>
<Field name="twentytwo" id="twentytwo" type="number" label="22k" component={renderField} />
<Field name="eighteen" id="eighteen" type="number" label="18k" autoFocus component={renderField} />
<Field name="fourteen" id="fourteen" type="number" label="14k" component={renderField} />
<Field name="nine" id="nine" type="number" label="9k" component={renderField} />
<Field name="argent" id="argent" type="number" label="Argent" component={renderField} />
<Field
name="tournee"
options={(
<>
{renderOptions}
</>
)}
id="tournee"
label="Dans la Tournee de"
component={renderSelect}
/>
<Button
type="submit"
fullWidth
variant="contained"
color="secondary"
className={classes.submit}
>
Ajouter
</Button>
</form>
</div>
<Box mt={8}>
<Copyright />
</Box>
</Container>
</Header>
这是我的 material ui redux-form 组件
渲染选择
export const renderSelect = ({
input, label, meta, id, className, fullWidth, options,
}) => (
<>
<FormControl fullWidth error={meta.touched && meta.error} variant="outlined" className={className} required>
<InputLabel htmlFor={id}>{label}</InputLabel>
<Select native {...input} id={id} label={label}>
{options}
</Select>
{renderFromHelper(meta.touched, meta.error)}
</FormControl>
</>
);
所以我通过向状态添加选项来解决它,运行 状态是代码
const GoldForm = ({
change, handleSubmit, weight, addGold, onSubmit, user, isAuthenticated,
}) => {
const classes = useStyles();
const [options, setOptions] = React.useState(null);
const [run, setRun] = React.useState(true);
useEffect(() => {
renderOptions();
}, [user]);
const renderOptions = () => {
if (run) {
const days = [];
function dateWithMonthsDelay(months) {
const date = new Date();
date.setDate(date.getDate() + months);
return date;
}
let i = 0;
for (let d = new Date(); d <= dateWithMonthsDelay(7); d.setDate(d.getDate() + 1)) {
if (isAuthenticated && user) {
const u = user.name.match(/\d/g);
if (u) {
const us = user.name.match(/\d/g).join('');
if (new Date(d).getDay() === 1
&& (us === '25'
|| us === '26'
|| us === '27'
|| us === '3')) {
days.push(new Date(d));
} else if (new Date(d).getDay() === 3 && (
us === '24'
|| us === '28'
|| us === '22'
|| us === '8'
|| us === '9'
|| us === '14'
)) {
days.push(new Date(d));
} else if ((new Date(d).getDay() === 2 || new Date(d).getDay() === 5) && (
us === '17'
|| us === '21'
|| us === '7'
|| us === '2'
|| us === '4'
|| us === '18'
|| us === '20'
|| us === '23'
|| us === '10'
|| us === '12'
|| us === '16'
|| us === '5'
|| us === '29'
|| us === '30'
|| us === '11'
|| us === '19'
)) {
days.push(new Date(d));
}
}
}
}
const a = days.map((d, index) => (
<React.Fragment key={index + 1}>
{i === 0 ? (<option aria-label="None" value="" />) : null}
{i += 1}
<option value={d}>
{moment(d).format('dddd - Do MMMM YYYY')}
</option>
</React.Fragment>
));
setOptions(a);
setRun(false);
}
};
return (
<Header>
<Container component="main" maxWidth="md">
<div className={classes.paper}>
<Typography component="h1" variant="h5">
GOLD
</Typography>
<form className={classes.form} onSubmit={handleSubmit(onSubmit)} noValidate>
<Field name="twentytwo" id="twentytwo" type="number" label="22k" component={renderField} />
<Field name="eighteen" id="eighteen" type="number" label="18k" autoFocus component={renderField} />
<Field name="fourteen" id="fourteen" type="number" label="14k" component={renderField} />
<Field name="nine" id="nine" type="number" label="9k" component={renderField} />
<Field name="argent" id="argent" type="number" label="Argent" component={renderField} />
<Field
name="tournee"
options={options}
id="tournee"
label="Dans la Tournee de"
component={renderSelect}
/>
<Button
type="submit"
fullWidth
variant="contained"
color="secondary"
className={classes.submit}
>
Ajouter
</Button>
</form>
</div>
<Box mt={8}>
<Copyright />
</Box>
</Container>
</Header>
);
};
所以我的问题是我正在动态呈现选项,当我单击 select 或组件重新呈现和更改选项的选项时,我需要单击两次才能 select select 中的一个选项。它正在重新渲染,因为它重新 运行 函数,我应该只将值 true/false 存储在反应钩子中并在第一个 运行 上更改它,这样它就不会重新 - 运行函数?
这是我的代码
这是创建选项的函数 渲染选项函数
const renderOptions = () => {
const days = [];
function dateWithMonthsDelay(months) {
const date = new Date();
date.setDate(date.getDate() + months);
return date;
}
let i = 0;
for (let d = new Date(); d <= dateWithMonthsDelay(7); d.setDate(d.getDate() + 1)) {
if (isAuthenticated && user) {
const u = user.name.match(/\d/g);
if (u) {
const us = user.name.match(/\d/g).join('');
if (new Date(d).getDay() === 1
&& (us === '25'
|| us === '26'
|| us === '27'
|| us === '3')) {
days.push(new Date(d));
} else if (new Date(d).getDay() === 3 && (
us === '24'
|| us === '28'
|| us === '22'
|| us === '8'
|| us === '9'
|| us === '14'
)) {
days.push(new Date(d));
} else if ((new Date(d).getDay() === 2 || new Date(d).getDay() === 5) && (
us === '17'
|| us === '21'
|| us === '7'
|| us === '2'
|| us === '4'
|| us === '18'
|| us === '20'
|| us === '23'
|| us === '10'
|| us === '12'
|| us === '16'
|| us === '5'
|| us === '29'
|| us === '30'
|| us === '11'
|| us === '19'
)) {
days.push(new Date(d));
}
}
}
}
return days.map((d) => (
<>
{i === 0 ? (<option aria-label="None" value="" />) : null}
{i += 1}
<option value={d}>
{moment(d).format('dddd - Do MMMM YYYY')}
</option>
</>
));
};
这是表单组件return
<Header>
<Container component="main" maxWidth="md">
<div className={classes.paper}>
<Typography component="h1" variant="h5">
GOLD
</Typography>
<form className={classes.form} onSubmit={handleSubmit(onSubmit)} noValidate>
<Field name="twentytwo" id="twentytwo" type="number" label="22k" component={renderField} />
<Field name="eighteen" id="eighteen" type="number" label="18k" autoFocus component={renderField} />
<Field name="fourteen" id="fourteen" type="number" label="14k" component={renderField} />
<Field name="nine" id="nine" type="number" label="9k" component={renderField} />
<Field name="argent" id="argent" type="number" label="Argent" component={renderField} />
<Field
name="tournee"
options={(
<>
{renderOptions}
</>
)}
id="tournee"
label="Dans la Tournee de"
component={renderSelect}
/>
<Button
type="submit"
fullWidth
variant="contained"
color="secondary"
className={classes.submit}
>
Ajouter
</Button>
</form>
</div>
<Box mt={8}>
<Copyright />
</Box>
</Container>
</Header>
这是我的 material ui redux-form 组件 渲染选择
export const renderSelect = ({
input, label, meta, id, className, fullWidth, options,
}) => (
<>
<FormControl fullWidth error={meta.touched && meta.error} variant="outlined" className={className} required>
<InputLabel htmlFor={id}>{label}</InputLabel>
<Select native {...input} id={id} label={label}>
{options}
</Select>
{renderFromHelper(meta.touched, meta.error)}
</FormControl>
</>
);
所以我通过向状态添加选项来解决它,运行 状态是代码
const GoldForm = ({
change, handleSubmit, weight, addGold, onSubmit, user, isAuthenticated,
}) => {
const classes = useStyles();
const [options, setOptions] = React.useState(null);
const [run, setRun] = React.useState(true);
useEffect(() => {
renderOptions();
}, [user]);
const renderOptions = () => {
if (run) {
const days = [];
function dateWithMonthsDelay(months) {
const date = new Date();
date.setDate(date.getDate() + months);
return date;
}
let i = 0;
for (let d = new Date(); d <= dateWithMonthsDelay(7); d.setDate(d.getDate() + 1)) {
if (isAuthenticated && user) {
const u = user.name.match(/\d/g);
if (u) {
const us = user.name.match(/\d/g).join('');
if (new Date(d).getDay() === 1
&& (us === '25'
|| us === '26'
|| us === '27'
|| us === '3')) {
days.push(new Date(d));
} else if (new Date(d).getDay() === 3 && (
us === '24'
|| us === '28'
|| us === '22'
|| us === '8'
|| us === '9'
|| us === '14'
)) {
days.push(new Date(d));
} else if ((new Date(d).getDay() === 2 || new Date(d).getDay() === 5) && (
us === '17'
|| us === '21'
|| us === '7'
|| us === '2'
|| us === '4'
|| us === '18'
|| us === '20'
|| us === '23'
|| us === '10'
|| us === '12'
|| us === '16'
|| us === '5'
|| us === '29'
|| us === '30'
|| us === '11'
|| us === '19'
)) {
days.push(new Date(d));
}
}
}
}
const a = days.map((d, index) => (
<React.Fragment key={index + 1}>
{i === 0 ? (<option aria-label="None" value="" />) : null}
{i += 1}
<option value={d}>
{moment(d).format('dddd - Do MMMM YYYY')}
</option>
</React.Fragment>
));
setOptions(a);
setRun(false);
}
};
return (
<Header>
<Container component="main" maxWidth="md">
<div className={classes.paper}>
<Typography component="h1" variant="h5">
GOLD
</Typography>
<form className={classes.form} onSubmit={handleSubmit(onSubmit)} noValidate>
<Field name="twentytwo" id="twentytwo" type="number" label="22k" component={renderField} />
<Field name="eighteen" id="eighteen" type="number" label="18k" autoFocus component={renderField} />
<Field name="fourteen" id="fourteen" type="number" label="14k" component={renderField} />
<Field name="nine" id="nine" type="number" label="9k" component={renderField} />
<Field name="argent" id="argent" type="number" label="Argent" component={renderField} />
<Field
name="tournee"
options={options}
id="tournee"
label="Dans la Tournee de"
component={renderSelect}
/>
<Button
type="submit"
fullWidth
variant="contained"
color="secondary"
className={classes.submit}
>
Ajouter
</Button>
</form>
</div>
<Box mt={8}>
<Copyright />
</Box>
</Container>
</Header>
);
};