如何使用 useContext hook 传递数据?
How to pass data using useContext hook?
我正在尝试通过上下文将 petData 传递给 SearchPage 组件。 petData 返回未定义。对我做错的任何帮助。
谢谢
Context.js
import { createContext } from "react";
const PetDataContext = createContext();
export default PetDataContext;
App.js
在 app.js 上,我正在获取数据并将其置于 axios 请求范围之外可访问的状态。然后我试图通过 useContext 挂钩传递它。
import PetDataContext from "./Context/context";
function App() {
const [petData, setPetData] = useState();
useEffect(() => {
axios
.get(`${BACK_PORT}/data`)
.then(function (response) {
setPetData(response.data);
})
}, []);
console.log(petData);
return (
<div className="App">
<PetDataContext.Provider value={{ petData }}>
<BrowserRouter>
<NavBar />
<Switch>
<Route path="/" component={MainSignedOut} exact />
<Route path="/mainsignedin" component={MainSignedIn} />
<Route path="/searchpage" component={SearchPage} />
<Route path="/mypets" component={MyPets} />
<Route path="/admin" component={Admin} />
<Route exact path="/pets/:id" component={PetPage} />
<Route component={err404} />
</Switch>
</BrowserRouter>
</PetDataContext.Provider>
</div>
);
}
export default App;
SearchPage.jsx
在 SearchPage 组件上,我试图通过 useContext 传递 petsData,但它返回未定义。
import PetDataContext from "../../Context/context";
function SearchPage() {
const { petData } = useContext(PetDataContext);
console.log("testing123", petData); //returns undefined
const [filter, setFilter] = React.useState("");
const filteredData = React.useMemo(() => {
if (filter == "") return petData;
return petData.filter(
(item) =>
item.name.toLowerCase().includes(filter) ||
item.breed.toLowerCase().includes(filter)
);
}, [petData, filter]);
return (
<>
<SearchBar onSearch={(searchTerm) => setFilter(searchTerm)} />
<div className="d-flex flex-wrap sp-body">
<DogCardsDisplayed petData={filteredData} />
</div>
</>
);
}
export default SearchPage;
您已使用以下代码行将初始值设置为 undefined
:
const [petData, setPetData] = useState();
如果这不是您想要的初始值,则在此处放置其他内容,例如空数组。
const [petData, setPetData] = useState([])
或者,您可以将其保留为未定义,并检查该值是否有可能在您使用它的地方使用。
const filteredData = React.useMemo(() => {
if (!petData) return []; //<--- added this
if (filter == "") return petData;
return petData.filter(
(item) =>
item.name.toLowerCase().includes(filter) ||
item.breed.toLowerCase().includes(filter)
);
}, [petData, filter]);
P.S:与您的错误无关,但以下可能会导致不需要存在的性能问题:
value={{ petData }}
App 每次渲染时,都会创建一个新对象。 petData 可能是相同的,但它周围的对象是新的。结果,即使没有任何改变,所有消费者也被迫重新呈现。
如果这是您需要提供的唯一数据,那么您可以删除对象并直接提供数组:
value={petData}
// And change how you consume it to:
const petData = useContext(PetDataContext);
如果您需要一个对象,因为您将提供多个东西,那么将对象存储起来,以便仅在其数据更改时重新创建它:
const value = React.useMemo(() => {
return { petData, somethingElse }
}, [petData, somethingElse]);
// ...
<PetDataContext.Provider value={value}>
我正在尝试通过上下文将 petData 传递给 SearchPage 组件。 petData 返回未定义。对我做错的任何帮助。
谢谢
Context.js
import { createContext } from "react";
const PetDataContext = createContext();
export default PetDataContext;
App.js
在 app.js 上,我正在获取数据并将其置于 axios 请求范围之外可访问的状态。然后我试图通过 useContext 挂钩传递它。
import PetDataContext from "./Context/context";
function App() {
const [petData, setPetData] = useState();
useEffect(() => {
axios
.get(`${BACK_PORT}/data`)
.then(function (response) {
setPetData(response.data);
})
}, []);
console.log(petData);
return (
<div className="App">
<PetDataContext.Provider value={{ petData }}>
<BrowserRouter>
<NavBar />
<Switch>
<Route path="/" component={MainSignedOut} exact />
<Route path="/mainsignedin" component={MainSignedIn} />
<Route path="/searchpage" component={SearchPage} />
<Route path="/mypets" component={MyPets} />
<Route path="/admin" component={Admin} />
<Route exact path="/pets/:id" component={PetPage} />
<Route component={err404} />
</Switch>
</BrowserRouter>
</PetDataContext.Provider>
</div>
);
}
export default App;
SearchPage.jsx
在 SearchPage 组件上,我试图通过 useContext 传递 petsData,但它返回未定义。
import PetDataContext from "../../Context/context";
function SearchPage() {
const { petData } = useContext(PetDataContext);
console.log("testing123", petData); //returns undefined
const [filter, setFilter] = React.useState("");
const filteredData = React.useMemo(() => {
if (filter == "") return petData;
return petData.filter(
(item) =>
item.name.toLowerCase().includes(filter) ||
item.breed.toLowerCase().includes(filter)
);
}, [petData, filter]);
return (
<>
<SearchBar onSearch={(searchTerm) => setFilter(searchTerm)} />
<div className="d-flex flex-wrap sp-body">
<DogCardsDisplayed petData={filteredData} />
</div>
</>
);
}
export default SearchPage;
您已使用以下代码行将初始值设置为 undefined
:
const [petData, setPetData] = useState();
如果这不是您想要的初始值,则在此处放置其他内容,例如空数组。
const [petData, setPetData] = useState([])
或者,您可以将其保留为未定义,并检查该值是否有可能在您使用它的地方使用。
const filteredData = React.useMemo(() => {
if (!petData) return []; //<--- added this
if (filter == "") return petData;
return petData.filter(
(item) =>
item.name.toLowerCase().includes(filter) ||
item.breed.toLowerCase().includes(filter)
);
}, [petData, filter]);
P.S:与您的错误无关,但以下可能会导致不需要存在的性能问题:
value={{ petData }}
App 每次渲染时,都会创建一个新对象。 petData 可能是相同的,但它周围的对象是新的。结果,即使没有任何改变,所有消费者也被迫重新呈现。
如果这是您需要提供的唯一数据,那么您可以删除对象并直接提供数组:
value={petData}
// And change how you consume it to:
const petData = useContext(PetDataContext);
如果您需要一个对象,因为您将提供多个东西,那么将对象存储起来,以便仅在其数据更改时重新创建它:
const value = React.useMemo(() => {
return { petData, somethingElse }
}, [petData, somethingElse]);
// ...
<PetDataContext.Provider value={value}>