在React中使用UseContext时获取未定义的值



我为在组件中使用useState而创建的上下文:

context.js:

const searchContext = React.createContext();

在这里,我用searchText创建了一个useState,初始状态为空字符串。

Header.js:

import { useState } from "react";
import { searchContext } from "./context";
import { useSelector } from 'react-redux';
import Motherboard from "./Components/Motherboard";
function Header() {
const[searchText,setSearchText] = useState("");
const cart = useSelector(state => state.cart);
return (
<div
style={{ backgroundColor: "#191C27", paddingLeft: 0, paddingRight: 0 }}
>
<Navbar
variant="light"
expand="lg"
style={{ backgroundColor: "#191C27" }}
>
<Container>
<Navbar.Toggle aria-controls="navbarScroll">
<img src={options} alt="options" width="30px" />
</Navbar.Toggle>
<Navbar.Brand className="mr-auto" href="#">
<Link to='home'>
<img
className="logoIcon"
src={logo}
alt="logo"
style={{ width: 130 }}
/>
</Link>           
</Navbar.Brand>
<Navbar.Collapse id="navbarScroll">
<Nav
className="ml-auto my-2 my-lg-0"
style={{ maxHeight: "100px", marginRight: "5%" }}
navbarScroll
>
<Nav.Link>
<Link to='/motherboard' className="links">
Motherboard
</Link>
</Nav.Link>
<Nav.Link onClick={(e) => e.preventDefault()}>
<Link to='/processor' className="links">
Processor
</Link>
</Nav.Link>
<Nav.Link>
<Link to='/ram' className="links">
RAM
</Link>
</Nav.Link>
<Nav.Link>
<Link to='/hdd' className="links">
HDD
</Link>
</Nav.Link>
<Nav.Link>
<Link to='/graphic' className="links">
Cabinet
</Link>
</Nav.Link>
</Nav>
</Navbar.Collapse>
<Form className="d-flex" style={{ marginRight: "2%" }}> 
<searchContext.Provider value={searchText}>
<Motherboard></Motherboard>
</searchContext.Provider>
<FormControl
type="search"
placeholder="Search"
onChange={event => {setSearchText(event.target.value)}}
className="mr-2"
aria-label="Search"
style={{background:'transparent', borderRadius:0, color:'white'}}
/>
</Form>

现在我尝试使用我的useContext,并在Motherboard组件中调用useStatesearchText。但是在运行时出现了一些undefined错误。

Motherboard.js:

import {searchContext} from '../context'
const dummy = Array.from(Array(10));
function Motherboard(props) {
let context = useContext(searchContext);
const [loading, setLoading] = React.useState(true);
// const [products, setProducts] = React.useState([]);
const products = useSelector((state) => state.products);
const dispatch = useDispatch();
useEffect(() => {
axios
.post("/product?limit=50&page=1&category=motherboard")
.then((res) => {
console.log(res, "res");
dispatch({
type: actionTypes.GET_PRODUCTS,
payload: res.data.products,
});
setLoading(false);
})
.catch((err) => {
setLoading(false);
console.log(err);
});
}, []);
const styleCol = {
backgroundColor: "#0F0F13",
};
if (loading) {
return (
<div className='loadDiv'>
<ClipLoader size="150" color="white" style={{marginTop: -200}}/>
</div>
);
}
return (
<div className="filterDiv">
<Banner />
<Container fluid="md">
<Row>
<Col lg={3} style={styleCol} className="colFilter">
<div>
<div style={{ backgroundColor: "#191C27" }}>
<Accordion>
<AccordionSummary
aria-controls="panel1a-content"
id="panel1a-header"
>
<Typography>SORT BY PRICE</Typography>
</AccordionSummary>
<div className="filterDiv">
<AccordionDetails>
<FormControl component="fieldset">
<RadioGroup aria-label="gender" name="gender1">
<FormControlLabel
value="hightolow"
control={<Radio />}
label="Highest to Lowest"
className="radioBtn"
/>
<FormControlLabel
value="lowtohigh"
control={<Radio />}
label="Lowest to Highest"
className="radioBtn"
/>
</RadioGroup>
</FormControl>
</AccordionDetails>
</div>
</Accordion>
</div>
<div style={{ backgroundColor: "#191C27" }}>
<Accordion>
<AccordionSummary
aria-controls="panel1a-content"
id="panel1a-header"
>
<Typography className="heading">SUB CATEGORY</Typography>
</AccordionSummary>
<div className="filterDiv">
<AccordionDetails>
<FormControl component="fieldset">
<RadioGroup aria-label="processor" name="prcocessor">
<FormControlLabel
value="hightolow"
control={<Radio />}
label="INTEL"
className="radioBtn"
/>
<FormControlLabel
value="lowtohigh"
control={<Radio />}
label="AMD"
className="radioBtn"
/>
</RadioGroup>
</FormControl>
</AccordionDetails>
</div>
</Accordion>
</div>
</div>
</Col>
<Col
xs={12}
lg={9}
sm={12}
md={12}
style={{ backgroundColor: "#0F0F13", paddingTop: 27 }}
>
<Row>
{products.filter((product) => {
if(context.searchText == '') {
return product
}
else if(product.productName.toLowerCase.includes(context.searchText.toLowerCase())){
return product
}}).map((product, index) => {
return (
<Col key={index} lg={4} md={6} xs={12} sm={6}>
<div

您可以尝试将值定义为对象。错误可能是由于该值不是目标

<searchContext.Provider value={{ searchText }}>
<Motherboard></Motherboard>
</searchContext.Provider>

在编写context.searchText时,必须将对象存储在提供者的值中:

<searchContext.Provider value={{ searchText }}>
<Motherboard />
</searchContext.Provider>

在MotherBoard.js中使用context而不是context.searchText,因为您正在传递一个字符串作为提供程序中的值,所以当使用useContext调用上下文时,它会给出您在搜索框中键入的提供程序的最新值。

最新更新