You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何持久化useLocation()路由传参数据及解决localStorage解析问题

有没有办法持久化存储useLocation()传递的数据?

我目前需要传递Firebase中嵌套集合里的数据,以下背景说明可直接跳转到核心问题部分。
通常如果只有单个集合,不会遇到相关问题,你可以在App.js中将用户UID传递到各个页面,示例如下:

function App() {

  const [user, setUser] = useState([]);

  useEffect(() => {
    auth.onAuthStateChanged((authUser) => {

      if (authUser) {
        setUser(authUser);
      } else {
        setUser(false);
      }
    })
  }, [])

 return (
    <div>
        <Router>
        <Switch>

          <Route path = "/SomePath">
            <SomeLocation user={user}/>
          </Route>

     </Switch>
  </Router>
</div>
   );
 }

export default App;

由于用户对象包含你需要的所有基础数据,通常不需要担心嵌套集合的访问问题,但如果使用多层嵌套集合会有什么问题?
如果要访问嵌套集合的全部数据也没问题,只需要用户信息即可,示例如下:

useEffect(() => { 
  const dbRef= db.collection("users").doc(user.uid).collection("someCollection")
  dbRef.onSnapshot(snapshot => {
    const tempData = [];
    snapshot.forEach((doc) => {
      const data = doc.data();
      
      tempData.push(data);
    });
    setDataSomewhere(tempData);
  })
 }, [user]);

但据我所知,仅通过用户信息无法获取嵌套集合中特定文档的UID数据。

核心问题部分

举个实际示例:我的业务场景是家长账号下添加学生数据,Firebase的集合结构为users -> [家长UID] -> students -> [学生UID] -> 学生详情字段,编辑表单的路由地址为独立路径/EDIT_STUDENT。
我现在的实现逻辑是:在数据表格页勾选学生后点击编辑图标,通过useLocation()传递学生数据到编辑页,代码如下:

//PATH-A (数据表格所在页面)

const editStudent= {
  pathname: '/EDIT_STUDENT',
  data: studentData
}

const editStudents= () => {
  if(studentData== 0)
  {
    window.alert("Select a student")
  }
  else {
    history.push(editStudent);
  }
};

///EDIT_STUDENT (编辑表单页)

let studentData= useLocation();
let data = studentData.data;

console.log(data)

const uid = data[0].uid // 这里可以拿到选中学生的专属UID

控制台打印的返回数据正常,但刷新页面后所有数据都会消失,因为无法再从前一个路由获取useLocation传递的数据,我的问题是:刷新页面时如何保留useLocation()传递过来的数据?
欢迎提供任何帮助、建议或代码示例。

补充说明

刷新页面后会报属性读取失败的错误。

更新

我参考建议尝试用localStorage存储数据,但读取时返回的是字符串,无法拆分访问对应字段,请问该如何解决?我存储数据的代码如下:

useEffect(() => {
  const localStorageEstData = window.localStorage.getItem("students");
  localStorageEstData && setStudentsData(JSON.parse(localStorageEstData));
}, []);

useEffect(() => {
  window.localStorage.setItem("students", JSON.stringify(studentsData));
}, [studentsData]);

我读取数据的代码及控制台输出如下:
let data = window.localStorage.getItem("estudiantes")
数据以完整字符串形式返回,我该如何解析拆分?


解决方案

最优方案:将学生ID放到路由参数中(推荐)

这是最符合前端路由设计规范的方案,不存在本地数据和服务端不一致的问题,刷新后也能正常读取数据。

  1. 修改路由定义,新增学生ID参数:
// App.js中的路由配置
<Route path="/EDIT_STUDENT/:studentId">
  <EditStudent user={user}/>
</Route>
  1. 修改表格页跳转逻辑:
const editStudents= () => {
  if(!studentData || studentData.length === 0) {
    window.alert("请先选择学生")
  } else {
    // 取选中的第一个学生的UID作为路由参数
    history.push(`/EDIT_STUDENT/${studentData[0].uid}`);
  }
};
  1. 编辑页读取参数并拉取最新数据:
import { useParams } from 'react-router-dom';

function EditStudent({user}) {
  // 读取路由中的学生ID参数
  const { studentId } = useParams();
  const [studentData, setStudentData] = useState(null);

  // 用ID直接从Firebase拉取最新的学生数据
  useEffect(() => {
    if(!user?.uid || !studentId) return;
    const studentRef = db.collection("users").doc(user.uid).collection("students").doc(studentId);
    const unsubscribe = studentRef.onSnapshot(snapshot => {
      if(snapshot.exists) {
        setStudentData(snapshot.data());
      }
    })
    // 组件卸载时取消监听
    return () => unsubscribe();
  }, [user, studentId]);

  // 后续直接用studentData渲染表单即可
}

方案二:修复localStorage使用问题

你当前使用localStorage的问题有两个:

  • 存储和读取的key不一致:存储时用的key是students,读取时用的是estudiantes,无法命中存储内容
  • 读取后没有反序列化:localStorage只能存储字符串,读取后需要用JSON.parse转成JS对象才能访问字段
    修正后的编辑页读取逻辑:
import { useLocation } from 'react-router-dom';

function EditStudent() {
  const [studentData, setStudentData] = useState(null);
  const location = useLocation();

  useEffect(() => {
    let rawData = location.data;
    // 如果路由中没有拿到数据,就从localStorage取
    if(!rawData) {
      const localString = window.localStorage.getItem("students");
      if(localString) {
        // 反序列化为JS对象
        rawData = JSON.parse(localString);
      }
    }
    if(rawData) {
      setStudentData(rawData);
    }
  }, [location])
}

注意该方案的局限性:用户清除浏览器缓存后数据会丢失,同时打开多个编辑页时存储内容会互相覆盖,仅适合临时使用。


内容的提问来源于stack exchange,提问作者React Enjoyer

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.29 23:15:01