(React Context 初学者)使用 react-router-dom 更改页面时,React Context 不启动

Posted

技术标签:

【中文标题】(React Context 初学者)使用 react-router-dom 更改页面时,React Context 不启动【英文标题】:(React Context Beginner) React Context doesn't stat when changing page using react-rooter-dom 【发布时间】:2021-02-19 18:06:16 【问题描述】:

我正在努力提高我的状态管理技能,所以我选择使用 REACT CONTEXT。我正在使用 axios 从后端服务器获取项目数据并将其存储在上下文中。

当我在/home 时,一切正常:状态更新,然后组件重新渲染,一切看起来都正常。但是当我转到/shopconsole.log(items) 时,它会返回一个空数组,而不是我之前得到的数据。

这是我的文件:

APP.JS

import logo from './logo.svg';
import './App.css';
import Nav from './components/navigations/NavBAr/Nav';
import HeaderSlides from './components/slides/header/HeaderSlide';
import Home from './components/Home/Home';
import Footer from './components/footer/Footer';
import  Route, Switch  from 'react-router-dom';
import Login from './components/Logs/Login/Login';
import  useState  from 'react';
import  ItemProvider  from './context/ItemContext';
import Register from './components/Logs/Register/Register';
import  UserProvider  from './context/UserContext';
import Shop from './components/Shop/Shop';



function App() 

  return (
    <ItemProvider>
      <UserProvider>
    <div className="App">
      <header>
        <Nav/>
      </header>
      <Route render=( location ) => (
            <Switch location=location>
              <Route exact path='/' render= () => (<Home/>)/>
              <Route path='/login' component=Login/>
              <Route path='/register' component=Register/>
              <Route path='/shop' component=Shop/>
            </Switch>
      ) />
      <footer>
        <Footer/>
      </footer>
    </div>
    </UserProvider>
    </ItemProvider>
  );


export default App;

ItemContext

import axios from 'axios';
import React,  useState, createContext, useEffect  from 'react';

export const ItemContext = createContext();

export function ItemProvider(props) 
    const [items, setItems] = useState([]);


    return (
        <ItemContext.Provider value=[items, setItems]>
            props.children
        </ItemContext.Provider>
    );

**Item.js ** 在 Home.js 上下文中调用

import React,  useContext, useEffect  from 'react';

//styles
import './Items.css'

//items
import  ItemContext  from '../../../../context/ItemContext'

export default function Items( toShow ) 

    const [items, setItems] = useContext(ItemContext);
    const data = items
    let stuff;
    if (data.length === 0) 
        console.log("loading");
     else 
        console.log(data);
        stuff = data.map((details, i) => 
            const  name, brand, gender, price, image, categorie  = details;
            while (gender === toShow) 
                return (
                    <div id="itemCard1">
                        <div className="itemImgWrap">
                            <img src=image  />
                        </div>
                        <div className="details">
                            <p className="detailsName">name</p>
                            <p className="brand">brand </p>
                            <p className="gender">gender</p>
                            <p className="price">price€</p>
                        </div>
                    </div>
                )
            
        )
    
    return (
        <div className="productItem">
            stuff
        </div>
    )


Views.js 在 Shop.js 上下文中调用不起作用

import React,  useContext, useEffect, useState  from 'react';


import './Views.css'

//items
import  ItemContext  from '../../../context/ItemContext'

export default function Views() 
    const [items, setItems] =  useContext(ItemContext);
    console.log(items);
    const data = items
    let stuff;
    if (data.length === 0) 
        console.log("nothing");
     else 
        console.log(data);
        stuff = data.map((details, i) => 
            const  name, brand, gender, price, image, categorie  = details;
           
                return (
                    <div id="itemCard1">
                        <div className="itemImgWrap">
                            <img src=image  />
                        </div>
                        <div className="details">
                            <p className="detailsName">name</p>
                            <p className="brand">brand </p>
                            <p className="gender">gender</p>
                            <p className="price">price€</p>
                        </div>
                    </div>
                )
        )
    

    return (
        <div className="viewsContainer">
            <div className="viewsGrid">
                stuff
            </div>
        </div>
    )

【问题讨论】:

你在哪里打电话给setItems?当你改变路线时,你是否在清除它们(没有意识到)?您需要显示这部分代码。 谢谢@Adam。你是对的,问题是我是使用浏览器 url 在页面之间导航。所以上下文正在清除...... 【参考方案1】:

所以我使用 react-router-dom &lt;Link/&gt; 解决了这个问题。

鉴于我想在我的页面初始化后执行路由, 我是通过 url 在页面之间导航的,所以上下文总是在清除,而应用程序刷新女巫不是我们想要的。所以我使用了&lt;Link/&gt;,然后它就可以工作了,因为&lt;Link/&gt; 可以帮助您在不刷新的情况下导航...

【讨论】:

以上是关于(React Context 初学者)使用 react-router-dom 更改页面时,React Context 不启动的主要内容,如果未能解决你的问题,请参考以下文章

在函数组件主体之外访问 React Context 值

在 NextJS 应用程序中使用 React Context API 会禁用静态站点生成器吗?

创建React工程:React工程模板

[react] 在React怎么使用Context?

[react] 怎么使用Context开发组件?

获取反应组件中的当前路径[重复]