【问题标题】:React: cannot acces component props when refreshing the pageReact:刷新页面时无法访问组件道具
【发布时间】:2021-08-18 20:19:49
【问题描述】:

当我在我的应用上重新加载“详细信息”页面(不是主页)时,出现错误:

“TypeError: 'country' 的属性 'flag' 未定义,因此无法解构。”

我猜由于数据是从主页传递到另一个,如果我们不从主页转到详细信息页面,我们就无法从 API 加载数据。

经过一些研究,我得出结论,我必须修改 webpack.config.js 中的一些内容,但是当我使用以下命令创建我的应用程序时:

npx create-react-app my-app

我很难找到 webpack 配置文件,我什至不确定这是否是解决方案。

主页上的卡片(点击后会转到特定国家/地区的详细信息页面):

import { Link } from 'react-router-dom';

const Card = ({country}) => {
    const {flag, name, population, subregion, capital} = country;

    const new_population = population.toLocaleString();

    const newTo = {
        pathname: `/details/${name}`,
        country: country
    };

    return <Link to={newTo} className='card'>

        <img src={flag} alt={name}></img>
        <div className='subCard'>
            <h2>{name}</h2>
            <p>Population: {new_population}</p>
            <p>Region: {subregion}</p>
            <p>Capital: {capital}</p>
        </div>

    </Link>;
}

export default Card;

点击卡片后进入的页面:

import { useLocation, Link } from 'react-router-dom';

const Details = () => {
    const { country } = useLocation();
    
    const { 
        flag, 
        name, 
        nativeName, 
        population, 
        region, 
        subregion, 
        capital, 
        topLevelDomain, 
        currencies, 
        languages, 
        borders } = country; 
        //arrays: currencies, languages, borders, topLevelDomain

    return <div className='details'>
        <Link to={`/`} >Back</Link>
        <img src={flag} alt={name}></img>
        
            //etc
    </div>;
export default Details;
}

我的主页:

import React, { useState, useEffect } from 'react';
import { useFetch } from './useFetch'
import Card from './Card';
import Searchbar from './Searchbar';

const Home = () => {
    const [url, setUrl] = useState('https://restcountries.eu/rest/v2/all');
    

    const { isLoading, countries, isError } = useFetch(url); //custom hook

    if(!isLoading && !isError){
        return <div className='home'>
        <Searchbar setUrl={setUrl}>
            <DropdownMenu setRegion={setRegion}></DropdownMenu>
            
        </Searchbar>
        <div className='cards'>
          {countries.map((country, index)=>{
              return <Card key={index} id={index} country={country} ></Card> 
          })} 
        </div>
    </div>;
//etc

我的App.js(不知道有没有必要):

import { BrowserRouter as Router, Route, Switch } from 'react-router-dom';

import Navbar from './Navbar';
//page(s)
import Home from './Home'
import Error from './Error'
import Details from './Details'

function App() {
  return (
    <Router>
    <Navbar></Navbar>
    <Switch>
      <Route exact path='/'>
        <Home />
      </Route>
      <Route path='/details/:id' children={<Details/>}></Route>
      <Route path='*'>
        <Error></Error>
      </Route>  
    </Switch>
  </Router>
  );
}

export default App;

您能否告诉我修改 webpack 配置文件是否是最好的解决方案?如果不是我该怎么办?

顺便说一句,如果您需要我没有在这里显示的代码,我很抱歉,告诉我我会修改我的帖子。

【问题讨论】:

  • 我不确定你提出的 webpack 解决方案,但我会做的是return null,而你的组件道具仍在加载。因此,例如,在您的Card 组件中,在您解构country 之前编写,检查country 是否为假,如果是则返回null。基本上:if (!country) return null

标签: javascript reactjs react-native webpack


【解决方案1】:

如果要使用&lt;Link&gt; 组件传递数据,则需要将其添加到state 变量中。

在您的卡片组件中,您的 newTo 变量应该是:

const newTo = { 
   pathname: `/details/${name}`,
   state: {country: country}
}

React Router - Link component

然后要访问详细信息页面上的country 变量,请使用

const {state} = useLocation()

const country = state.country

【讨论】:

  • 除此之外,您还应该在详细信息页面上检查country 对象是否存在于location.state 中。如果没有(刷新页面或访问单独选项卡上的链接时可能会发生这种情况),那么您应该在详细信息页面上获取数据,然后在加载后呈现它。
  • 使用正确的语法(来自您的第一条评论)足以避免刷新时出现错误,但我会稍微调整一下或获取详细信息,如您所说的能够访问详细信息新标签页,谢谢
  • 是的,这在共享链接时特别有用。如果有人在浏览器上打开该链接,他们将无法访问 location 属性中的共享状态。
【解决方案2】:

这不是 Webpack 配置。

问题是您没有正确输入国家/地区。在您的详细信息功能中,console.log(countries) 并查看传入的内容。

【讨论】:

    【解决方案3】:

    不建议在Link 中保留状态,恕我直言。因为获得状态的唯一方法是单击卡片组件。但是这里的问题是,一旦您点击进入相应页面的卡片并且点击 refresh 。您在location 下的状态将为undefined,因为刷新页面会导致您的应用重新渲染。

    因此,如果您想跨路线保留状态,那么我建议您使用

    React Context 或其他状态管理库,例如 reduxmobx

    【讨论】:

    • 我觉得还是用 useContext 会更好,我可能会重构一下,谢谢
    猜你喜欢
    • 2019-02-27
    • 2019-11-05
    • 1970-01-01
    • 2017-07-02
    • 2020-05-04
    • 2018-12-17
    • 1970-01-01
    • 1970-01-01
    • 2021-01-09
    相关资源
    最近更新 更多