如何将Register组件数据传至App.js并解决Router嵌套错误
问题解决:通过Context传递表单数据并修复Router嵌套错误
错误原因
你碰到的You cannot render a <Router> inside another <Router>错误,是因为在Register组件里直接渲染了<App sendData={setUserData} />,而App组件本身包含<BrowserRouter>,导致整个应用出现多个Router实例——React Router要求全局只能有一个Router根节点。
解决方案:用React Context实现跨组件数据共享,同时保留表单状态
步骤1:创建表单数据Context
新建FormContext.js文件,封装表单数据的状态管理:
import { createContext, useContext, useState } from "react"; const FormContext = createContext(); export function FormProvider({ children }) { // 初始化表单默认数据 const [formData, setFormData] = useState({ name: "Test one", mobile: "234242342", email: "test1@test.com", notes: "How are you doing ?", selectedEmails: [] // 存储多选的邮箱值 }); return ( <FormContext.Provider value={{ formData, setFormData }}> {children} </FormContext.Provider> ); } // 自定义Hook,简化Context调用 export function useFormContext() { return useContext(FormContext); }
步骤2:修改App.js,整合路由并注入Context
把FormProvider包裹在Router外层,确保所有路由组件都能访问表单数据;同时合并冗余的Routes标签:
import "./styles.css"; import { BrowserRouter, Routes, Route } from "react-router-dom"; import Home from "./components/home"; import Register from "./components/register"; import { FormProvider } from "./FormContext"; export default function App() { return ( <div className="App"> <FormProvider> <BrowserRouter> <Routes> <Route path="/" element={<Home />} /> <Route path="/Register" element={<Register />} /> </Routes> </BrowserRouter> </FormProvider> </div> ); }
步骤3:重构Register组件,使用Context管理表单
删除对App组件的导入和渲染,改用useFormContext获取数据和更新方法,给表单元素绑定状态同步逻辑:
import Select from "react-select"; import { useNavigate } from "react-router-dom"; import { useFormContext } from "../FormContext"; const options = [ { value: "test1@test.com", label: "test1@test.com" }, { value: "test2@test.com", label: "test2@test.com" }, { value: "test3@test.com", label: "test3@test.com" } ]; const Register = () => { const navigate = useNavigate(); const { formData, setFormData } = useFormContext(); // 处理普通输入框的变化 const handleInputChange = (e) => { const { name, value } = e.target; setFormData(prev => ({ ...prev, [name]: value })); }; // 处理react-select的多选变化 const handleSelectChange = (selectedOptions) => { setFormData(prev => ({ ...prev, selectedEmails: selectedOptions.map(opt => opt.value) })); }; const moveBack = () => { navigate("/"); }; return ( <div className="wrapper"> <h1>Lets us Know</h1> <form> <input type="text" name="name" value={formData.name} onChange={handleInputChange} /> <br></br> <br></br> <input type="text" name="mobile" value={formData.mobile} onChange={handleInputChange} /> <br></br> <br></br> <Select isMulti options={options} value={options.filter(opt => formData.selectedEmails.includes(opt.value))} onChange={handleSelectChange} /> <br></br> <textarea name="notes" value={formData.notes} onChange={handleInputChange} ></textarea> <hr></hr> <button type="submit">Submit</button> <button type="button" onClick={moveBack}>Back</button> </form> </div> ); }; export default Register;
效果说明
现在从Home页面返回Register页面时,表单里已输入的内容会自动保留,同时Router嵌套的错误也被修复。
内容的提问来源于stack exchange,提问作者soccerway
相关产品推荐
相关产品推荐

