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

React路由/hotels页面报错:无法读取null的destination属性

问题排查:访问/hotels路由出现TypeError错误

问题描述

我是React新手,尝试通过/hotels路由展示酒店列表页面,但访问该路径时出现报错:Uncaught TypeError: Cannot read properties of null (reading 'destination'),页面空白;而访问/hotels/:id路径可正常显示。

报错详情

Uncaught TypeError: Cannot read properties of null (reading 'destination')
 at List (List.jsx:12:1)
at renderWithHooks (react-dom.development.js:16305:1)
at mountIndeterminateComponent (react-dom.development.js:20074:1)
at beginWork (react-dom.development.js:21587:1)
at beginWork$1 (react-dom.development.js:27426:1)
at performUnitOfWork (react-dom.development.js:26557:1)
at workLoopSync (react-dom.development.js:26466:1)
at renderRootSync (react-dom.development.js:26434:1)
at recoverFromConcurrentError (react-dom.development.js:25850:1)
at performConcurrentWorkOnRoot (react-dom.development.js:25750:1

相关代码

App.js

import { BrowserRouter, Routes, Route } from 'react-router-dom';

import Home from './pages/home/Home';
import List from './pages/list/List';
import Hotel from './pages/hotel/Hotel';

function App() {
  return (
    <BrowserRouter>
      <Routes>
        <Route path='/' element={<Home />} />
        <Route path='/hotels' element={<List />} />
        <Route path='/hotels/:id' element={<Hotel />} />
      </Routes>
    </BrowserRouter>
  );
}

export default App;

List.js

import './list.css';
import Navbar from '../../components/navbar/Navbar';
import Header from '../../components/header/Header';
import { useLocation } from 'react-router-dom';
import { useState } from 'react';
import { format } from 'date-fns';
import { DateRange } from 'react-date-range';
import SearchItem from '../../components/searchItem/SearchItem';

const List = () => {
  const location = useLocation();
  const [destination, setDestination] = useState(location.state.destination);
  const [date, setDate] = useState(location.state.date);
  const [openDate, setOpenDate] = useState(false);
  const [options, setOptions] = useState(location.state.options);

  return (
    <div>
      <Navbar />
      <Header type='list' />
      <div className='listContainer'>
        <div className='listWrapper'>
          <div className='listSearch'>
            <h1 className='lsTitle'>Search</h1>
            <div className='lsItem'>
              <label>Destination</label>
              <input placeholder={destination} type='text' />
            </div>
            <div className='lsItem'>
              <label>Check-in Date</label>
              <span onClick={() => setOpenDate(!openDate)}>{`${format(
                date[0].startDate,
                'MM/dd/yyyy'
              )} to ${format(date[0].endDate, 'MM/dd/yyyy')}`}</span>
              {openDate && (
                <DateRange
                  onChange={(item) => setDate([item.selection])}
                  minDate={new Date()}
                  ranges={date}
                />
              )}
            </div>
            <div className='lsItem'>
              <label>Options</label>
              <div className='lsOptions'>
                <div className='lsOptionItem'>
                  <span className='lsOptionText'>
                    Min price <small>per night</small>
                  </span>
                  <input type='number' className='lsOptionInput' />
                </div>
                <div className='lsOptionItem'>
                  <span className='lsOptionText'>
                    Max price <small>per night</small>
                  </span>
                  <input type='number' className='lsOptionInput' />
                </div>
                <div className='lsOptionItem'>
                  <span className='lsOptionText'>Adult</span>
                  <input
                    type='number'
                    min={1}
                    className='lsOptionInput'
                    placeholder={options.adult}
                  />
                </div>
                <div className='lsOptionItem'>
                  <span className='lsOptionText'>Children</span>
                  <input
                    type='number'
                    min={0}
                    className='lsOptionInput'
                    placeholder={options.children}
                  />
                </div>
                <div className='lsOptionItem'>
                  <span className='lsOptionText'>Room</span>
                  <input
                    type='number'
                    min={1}
                    className='lsOptionInput'
                    placeholder={options.room}
                  />
                </div>
              </div>
            </div>
            <button>Search</button>
          </div>
          <div className='listResult'>
            <SearchItem />
            <SearchItem />
            <SearchItem />
            <SearchItem />
            <SearchItem />
            <SearchItem />
            <SearchItem />
            <SearchItem />
            <SearchItem />
          </div>
        </div>
      </div>
    </div>
  );
};

export default List;

问题原因与解决办法

原因

直接访问/hotels路由时,location.state的值为null(只有通过路由跳转并主动传递state参数时,location.state才会有值),此时尝试读取location.state.destination就会触发Cannot read properties of null的错误。

解决办法

  1. 给state设置默认值:使用可选链操作符?.避免读取null属性,同时给状态设置合理的默认值:
const List = () => {
  const location = useLocation();
  // 处理null情况,添加默认值
  const [destination, setDestination] = useState(location.state?.destination || '');
  const [date, setDate] = useState(location.state?.date || [{ startDate: new Date(), endDate: new Date() }]);
  const [openDate, setOpenDate] = useState(false);
  const [options, setOptions] = useState(location.state?.options || { adult: 1, children: 0, room: 1 });

  // ... 其余代码保持不变
};
  1. 处理日期格式化逻辑:上述默认值中已经包含了startDate和endDate,确保format函数能正常运行,不会再出现读取null属性的问题。

  2. 添加路由跳转的state传递(可选):如果希望从其他页面跳转到/hotels时携带参数,比如从Home页面跳转,可使用navigate函数传递state:

// 在Home页面中
import { useNavigate } from 'react-router-dom';

const Home = () => {
  const navigate = useNavigate();

  const handleSearch = () => {
    navigate('/hotels', {
      state: {
        destination: '示例城市',
        date: [{ startDate: new Date(), endDate: new Date() }],
        options: { adult: 1, children: 0, room: 1 }
      }
    });
  };

  // ... 其余代码
};

内容的提问来源于stack exchange,提问作者spooky wooky

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.18 20:25:28