【发布时间】:2020-09-27 23:40:28
【问题描述】:
我有一个名为 Np02 的反应钩子,它显示通过文件输入选择的照片并将它们保存到状态。当用户选择文件时,它们会以网格形式显示给他。这可行,但是有一些功能我想删除选定的图像,而这没有。函数 removeImage 运行,输出我期望的数组,但状态不会改变。我已经尝试将 setImages 移动到函数 removeImages 或其他地方,但状态本身不会改变,当我在图像上添加 useEffect 时,它只会在我选择图像时改变,但在我想删除它们时不会改变。 为什么状态没有改变?
const MAX_IMAGES = 5;
const blankImage = 'https://static.thenounproject.com/png/187803-200.png';
function fillWithBlanks(arr) {
const blanks = new Array(MAX_IMAGES - arr.length).fill(blankImage);
return [...arr, ...blanks];
};
const Np02 = ({setForm}) => {
const classes = useStyles();
const fileInput = useRef<HTMLInputElement | null>(null);
const dispatch = useDispatch();
const NPData = useSelector(getNPStepData);
const [values, setValues] = useState(NPData[1]);
const [images, setImages] = useState<any[]>(fillWithBlanks([]));
useEffect(() => {
setTimeout(() => {
setForm(checkFormValidity);
}, 200);
}, [values]);
const checkFormValidity = (): boolean => {
dispatch(submitStep(1, values));
return true;
};
const imageInputChanged = (e) => {
const files = e.target.files;
const result: any = [];
let fileCounter = 0;
for (var i = 0; i < files.length; i++) {
const file = files.item(i);
let reader = new FileReader();
reader.readAsDataURL(file);
reader.onload = (e) => {
result.push(reader.result);
fileCounter++;
if (fileCounter >= files.length) {
let uploadedImg = [...(images.filter((value) => value !== blankImage)), ...result];
if (MAX_IMAGES < uploadedImg.length) {
uploadedImg = uploadedImg.slice(uploadedImg.length - MAX_IMAGES);
}
setImages(fillWithBlanks(uploadedImg));
}
};
}
};
const removeImage = (id) => {
let arr = images;
arr[id] = blankImage;
console.log(arr); // this outputs right version of array
return arr;
};
return (
<div>
<label htmlFor="raised-button-file" className={classes.buttonLabel}>
<Button variant="contained" color="secondary" component="span">
Nahraj fotky
</Button>
</label>
<FormHelperText className={classes.helperText}>Nahraj alespoň dvě různé fotky tvého
předmětu</FormHelperText>
<ImagesGrid images={images} imageClicked={(id) => setImages(removeImage(id))}/>
<TextField
className={classes.textarea}
label="Popis"
variant="filled"
helperText="Zde popiš předmět, pro případné zájemce"
multiline
rows={6}
value={values.desc}
onChange={(e) => setValues({desc: e.target.value})}
/>
<input
ref={fileInput}
accept="image/*"
className={classes.input}
id="raised-button-file"
multiple
type="file"
onChange={imageInputChanged}
/>
</div>
);
};
export default Np02;
这是负责将图像绘制到网格的组件。
const ImagesGrid = (props: iImagesGrid) => {
const classes = useStyles();
const spacing = 0;
return (
<div className={classes.root}>
<Grid className={classes.fullHeight} container spacing={spacing} direction="row"
justify="center"
alignItems="stretch">
<Grid item xs={6} onClick={() => props.imageClicked(0)}>
<GridImage url={props.images[0]} title={'teehee'} />
</Grid>
<Grid item xs={6} className={classes.fullHeight}>
<Grid container className={classes.halfHeight} item xs={12}>
<Grid item xs={6} onClick={() => props.imageClicked(1)}>
<GridImage url={props.images[1]} title={'teehee'}/>
</Grid>
<Grid item xs={6} onClick={() => props.imageClicked(2)}>
<GridImage url={props.images[2]} title={'teehee'}/>
</Grid>
</Grid>
<Grid item className={classes.halfHeight} container xs={12}>
<Grid item xs={6} onClick={() => props.imageClicked(3)}>
<GridImage url={props.images[3]} title={'teehee'}/>
</Grid>
<Grid item xs={6} onClick={() => props.imageClicked(4)}>
<GridImage url={props.images[4]} title={'teehee'}/>
</Grid>
</Grid>
</Grid>
</Grid>
</div>
);
};
export default ImagesGrid;
【问题讨论】:
标签: javascript reactjs react-hooks react-state-management