如果您要进行子对父(而不是父对子)通信,通过该管道传递数据的惯用方式是使用 React 上下文。
创建一个名为 contexts/file.js 的文件,该文件将公开初始上下文。
import {createContext} from "react";
export const FileContext = createContext();
创建一个名为 hooks/file.js 的文件,该文件将定义一个自定义挂钩以使用创建的上下文。
import {useContext} from "react";
import {FileContext} from "../contexts/file";
export const useFile = () => useContext(FileContext);
创建一个名为providers/file.jsx 的文件,该文件将公开所需的值(用于存储文件的状态和用于更新该状态值的函数)。如果您的文件通信需要更多功能,您可以在此处添加它们并将它们公开给您的所有组件。
import React, {useState, useMemo} from "react";
import {FileContext} from "../contexts/file";
export const FileProvider = ({children}) => {
const [file, setFile] = useState("");
const value = useMemo(() => ({file, setFile}), [file, setFile]);
return (
<FileContext.Provider value={value}>
{children}
</FileContext.Provider>
);
};
在您的主入口点中添加提供程序,以便在您的主应用程序组件中定义的每个组件都可以访问来自提供程序的公开值。
import React, {StrictMode} from "react";
import {createRoot} from "react-dom/client";
import {FileProvider} from "./providers/file";
import App from "./components/app";
createRoot(document.getElementById("root")).render(
<StrictMode>
<FileProvider>
<App />
</FileProvider>
</StrictMode>
);
现在,您可以创建将使用自定义文件挂钩来检索文件并侦听文件更改的父组件。
import React, {useEffect} from "react";
import {useFile} from "../hooks/file";
const ParentComponent = ({children}) => {
const {file} = useFile();
useEffect(() => {
console.log("[PARENT] File has changed");
console.log(file);
}, [file]);
return (
<>
<h1>
Parent
</h1>
{children}
</>
);
};
export default ParentComponent;
您的子组件也将使用自定义挂钩来检索提供的函数以更新文件(因此,将其发送给父组件)。
import React, {useCallback} from "react";
import {useFile} from "../hooks/file";
const ChildComponent = () => {
const {setFile} = useFile();
const handleFileChange = useCallback(changeEvent => {
console.log("[CHILD] passing the file to the parent...");
setFile(changeEvent.currentTarget.files[0]);
}, [setFile]);
const handleFormSubmit = useCallback(submitEvent => {
submitEvent.preventDefault();
}, []);
return (
<>
<h2>
Child
</h2>
<form onSubmit={handleFormSubmit}>
<input type="file" onChange={handleFileChange} />
</form>
</>
);
};
export default ChildComponent;
现在您可以将这些添加到您的主应用组件中。
import React from "react";
import ParentComponent from "./parent";
import ChildComponent from "./child";
const App = () => (
<ParentComponent>
<ChildComponent />
</ParentComponent>
);
export default App;
现在您可以使用新创建的上下文提供程序从子节点到父节点,甚至从父节点到子节点,或任意嵌套组件树配置进行通信。
您可以找到更多信息: