反应改变状态下一个组件
React change state next component
我必须为输入类型文件创建上传文件唯一组件,为此我使用 react-dropzone
库进行拖放,并在页面中使用该组件 4 次。最初最初,除了第一个组件之外,其他组件必须被禁用,但加载文件后,下一个组件必须更改状态为disable = {true}。如何使用useState正确实现逻辑?
UploadFile.js
const UploadFile = ({ visible }) => {
const [active, setActive] = useState(false);
useEffect(() => {
if (!visible) {
setActive(true);
}
}, [visible]);
console.log(visible);
const { getRootProps, getInputProps, open, acceptedFiles } = useDropzone({
noClick: true,
noKeyboard: true,
disabled: active
});
const files = acceptedFiles.map((file) => (
<li key={file.path}>
{file.path} - {file.size} bytes
</li>
));
return (
<>
<div className="file-input">
<div {...getRootProps({ className: "dropzone" })}>
<input {...getInputProps()} />
<p>Drag drop some files here</p>
<button type="button" onClick={open} disabled={active}>
Open File Dialog
</button>
</div>
<aside>
<h4>Files</h4>
<ul>{files}</ul>
</aside>
</div>
</>
);
};
App.js
export default function App() {
return (
<div className="App">
<div className="upload-file">
<h4>Please select file</h4>
<div>
<p>Images</p>
<UploadFile visible />
<UploadFile visible={false} />
</div>
<div>
<p>Documents</p>
<UploadFile visible={false} />
<UploadFile visible={false} />
</div>
<br />
<button type="submit" disabled={true}>
SEND
</button>
</div>
</div>
);
}
可以使用react context来创建各个组件之间的关系,在第一个文件drop之后,可以去上传组件的下一个索引
UploadFile.js
import React, { useEffect, useState, useContext } from "react";
import { useDropzone } from "react-dropzone";
import { DragContext } from "./App";
const UploadFile = ({ index = 0 }) => {
const { currentIndex, setCurrentIndex } = useContext(DragContext); // use context
const [active, setActive] = useState(false);
useEffect(() => {
if (index !== currentIndex) { // compare to active
setActive(true);
} else {
setActive(false);
}
}, [currentIndex, index]);
console.log(active);
const { getRootProps, getInputProps, open, acceptedFiles } = useDropzone({
noClick: true,
noKeyboard: true,
disabled: active,
onDropAccepted: () => {
setCurrentIndex(currentIndex + 1);
}
});
const files = acceptedFiles.map((file) => (
<li key={file.path}>
{file.path} - {file.size} bytes
</li>
));
return (
<>
<div className="file-input">
<div {...getRootProps({ className: "dropzone" })}>
<input {...getInputProps()} />
<p>Drag drop some files here</p>
<button type="button" onClick={open} disabled={active}>
Open File Dialog
</button>
</div>
<aside>
<h4>Files</h4>
<ul>{files}</ul>
</aside>
</div>
</>
);
};
export default UploadFile;
App.js
import React, { createContext, useState } from "react";
import UploadFile from "./UploadFile";
import "./styles.css";
export const DragContext = createContext({});
export default function App() {
const [currentIndex, setCurrentIndex] = useState(0); // compare with index
return (
<div className="App">
<DragContext.Provider value={{ currentIndex, setCurrentIndex }}>
<div className="upload-file">
<h4>Please select file</h4>
<div>
<p>Images</p>
<UploadFile index={0} />
<UploadFile index={1} />
</div>
<div>
<p>Documents</p>
<UploadFile index={2} />
<UploadFile index={3} />
</div>
<br />
<button type="submit" disabled={true}>
SEND
</button>
</div>
</DragContext.Provider>
</div>
);
}
您只能使用一种状态 currentStep
作为您 parent 的参考。
import React, { useCallback, useState } from "react";
import UploadFile from "./UploadFile";
import "./styles.css";
export default function App() {
const [currentStep, setCurrentStep] = useState(1)
const nextStep = useCallback(() => {setCurrentStep(crr => crr + 1)}, [])
return (
<div className="App">
<div className="upload-file">
<h4>Please select file</h4>
<div>
<p>Images</p>
<UploadFile nextStep={nextStep} currentStep={currentStep} step={1} />
<UploadFile nextStep={nextStep} currentStep={currentStep} step={2} />
</div>
<div>
<p>Documents</p>
<UploadFile nextStep={nextStep} currentStep={currentStep} step={3} />
<UploadFile nextStep={nextStep} currentStep={currentStep} step={4} />
</div>
<br />
<button type="submit" disabled={true}>
SEND
</button>
</div>
</div>
);
}
在上传文件时不需要设置状态,只需将步骤与当前步骤进行比较以检查是否启用。您还需要检查 step === currentStep
一旦接受放置,否则如果您对同一字段进行多次更改,将继续打开其他字段。
import React from "react";
import { useDropzone } from "react-dropzone";
const UploadFile = ({ nextStep, step, currentStep }) => {
const onDropAccepted = () => {
if(step === currentStep) nextStep()
}
const { getRootProps, getInputProps, open, acceptedFiles } = useDropzone({
noClick: true,
noKeyboard: true,
disabled: step > currentStep,
onDropAccepted
});
const files = acceptedFiles.map((file) => (
<li key={file.path}>
{file.path} - {file.size} bytes
</li>
));
return (
<>
<div className="file-input">
<div {...getRootProps({ className: "dropzone" })}>
<input {...getInputProps()} />
<p>Drag drop some files here</p>
<button type="button" onClick={open} disabled={step > currentStep}>
Open File Dialog
</button>
</div>
<aside>
<h4>Files</h4>
<ul>{files}</ul>
</aside>
</div>
</>
);
};
export default UploadFile;
我必须为输入类型文件创建上传文件唯一组件,为此我使用 react-dropzone
库进行拖放,并在页面中使用该组件 4 次。最初最初,除了第一个组件之外,其他组件必须被禁用,但加载文件后,下一个组件必须更改状态为disable = {true}。如何使用useState正确实现逻辑?
UploadFile.js
const UploadFile = ({ visible }) => {
const [active, setActive] = useState(false);
useEffect(() => {
if (!visible) {
setActive(true);
}
}, [visible]);
console.log(visible);
const { getRootProps, getInputProps, open, acceptedFiles } = useDropzone({
noClick: true,
noKeyboard: true,
disabled: active
});
const files = acceptedFiles.map((file) => (
<li key={file.path}>
{file.path} - {file.size} bytes
</li>
));
return (
<>
<div className="file-input">
<div {...getRootProps({ className: "dropzone" })}>
<input {...getInputProps()} />
<p>Drag drop some files here</p>
<button type="button" onClick={open} disabled={active}>
Open File Dialog
</button>
</div>
<aside>
<h4>Files</h4>
<ul>{files}</ul>
</aside>
</div>
</>
);
};
App.js
export default function App() {
return (
<div className="App">
<div className="upload-file">
<h4>Please select file</h4>
<div>
<p>Images</p>
<UploadFile visible />
<UploadFile visible={false} />
</div>
<div>
<p>Documents</p>
<UploadFile visible={false} />
<UploadFile visible={false} />
</div>
<br />
<button type="submit" disabled={true}>
SEND
</button>
</div>
</div>
);
}
可以使用react context来创建各个组件之间的关系,在第一个文件drop之后,可以去上传组件的下一个索引
UploadFile.js
import React, { useEffect, useState, useContext } from "react";
import { useDropzone } from "react-dropzone";
import { DragContext } from "./App";
const UploadFile = ({ index = 0 }) => {
const { currentIndex, setCurrentIndex } = useContext(DragContext); // use context
const [active, setActive] = useState(false);
useEffect(() => {
if (index !== currentIndex) { // compare to active
setActive(true);
} else {
setActive(false);
}
}, [currentIndex, index]);
console.log(active);
const { getRootProps, getInputProps, open, acceptedFiles } = useDropzone({
noClick: true,
noKeyboard: true,
disabled: active,
onDropAccepted: () => {
setCurrentIndex(currentIndex + 1);
}
});
const files = acceptedFiles.map((file) => (
<li key={file.path}>
{file.path} - {file.size} bytes
</li>
));
return (
<>
<div className="file-input">
<div {...getRootProps({ className: "dropzone" })}>
<input {...getInputProps()} />
<p>Drag drop some files here</p>
<button type="button" onClick={open} disabled={active}>
Open File Dialog
</button>
</div>
<aside>
<h4>Files</h4>
<ul>{files}</ul>
</aside>
</div>
</>
);
};
export default UploadFile;
App.js
import React, { createContext, useState } from "react";
import UploadFile from "./UploadFile";
import "./styles.css";
export const DragContext = createContext({});
export default function App() {
const [currentIndex, setCurrentIndex] = useState(0); // compare with index
return (
<div className="App">
<DragContext.Provider value={{ currentIndex, setCurrentIndex }}>
<div className="upload-file">
<h4>Please select file</h4>
<div>
<p>Images</p>
<UploadFile index={0} />
<UploadFile index={1} />
</div>
<div>
<p>Documents</p>
<UploadFile index={2} />
<UploadFile index={3} />
</div>
<br />
<button type="submit" disabled={true}>
SEND
</button>
</div>
</DragContext.Provider>
</div>
);
}
您只能使用一种状态 currentStep
作为您 parent 的参考。
import React, { useCallback, useState } from "react";
import UploadFile from "./UploadFile";
import "./styles.css";
export default function App() {
const [currentStep, setCurrentStep] = useState(1)
const nextStep = useCallback(() => {setCurrentStep(crr => crr + 1)}, [])
return (
<div className="App">
<div className="upload-file">
<h4>Please select file</h4>
<div>
<p>Images</p>
<UploadFile nextStep={nextStep} currentStep={currentStep} step={1} />
<UploadFile nextStep={nextStep} currentStep={currentStep} step={2} />
</div>
<div>
<p>Documents</p>
<UploadFile nextStep={nextStep} currentStep={currentStep} step={3} />
<UploadFile nextStep={nextStep} currentStep={currentStep} step={4} />
</div>
<br />
<button type="submit" disabled={true}>
SEND
</button>
</div>
</div>
);
}
在上传文件时不需要设置状态,只需将步骤与当前步骤进行比较以检查是否启用。您还需要检查 step === currentStep
一旦接受放置,否则如果您对同一字段进行多次更改,将继续打开其他字段。
import React from "react";
import { useDropzone } from "react-dropzone";
const UploadFile = ({ nextStep, step, currentStep }) => {
const onDropAccepted = () => {
if(step === currentStep) nextStep()
}
const { getRootProps, getInputProps, open, acceptedFiles } = useDropzone({
noClick: true,
noKeyboard: true,
disabled: step > currentStep,
onDropAccepted
});
const files = acceptedFiles.map((file) => (
<li key={file.path}>
{file.path} - {file.size} bytes
</li>
));
return (
<>
<div className="file-input">
<div {...getRootProps({ className: "dropzone" })}>
<input {...getInputProps()} />
<p>Drag drop some files here</p>
<button type="button" onClick={open} disabled={step > currentStep}>
Open File Dialog
</button>
</div>
<aside>
<h4>Files</h4>
<ul>{files}</ul>
</aside>
</div>
</>
);
};
export default UploadFile;