[英]Change Context API Class to function hooks in React
我试图将“上下文 API”的“类组件”更改为“钩子”,但我已经徘徊了几个小时并被卡住了。 在“类组件”环境中运行良好。 但是“钩子”不起作用。
在 class 中,在 'filterRoom()' 中,tempRooms 变量 'filter(((room===>room.type===type);' 成为过滤器,但在挂钩中,整个 tempRooms 是 output 而不是过滤器。
详细代码在我的 GitHub 中。
在分支中,master 使用 hook 完成,class 使用 class 完成。 GitHub 地址
https://github.com/lhk3337/beachResort 。
import React, { Component } from "react";
import items from "./data";
const RoomContext = React.createContext();
class RoomProvider extends Component {
state = {
rooms: [],
sortedRooms: [],
featuredRooms: [],
loading: true,
type: "all",
capacity: 1,
price: 0,
minPrice: 0,
maxPrice: 0,
minSize: 0,
maxSize: 0,
breakfast: false,
pets: false,
};
componentDidMount() {
let rooms = this.formatdata(items);
let featuredRooms = rooms.filter((room) => room.featured === true);
let maxPrice = Math.max(...rooms.map((item) => item.price));
let maxSize = Math.max(...rooms.map((item) => item.size));
this.setState({
rooms,
featuredRooms,
sortedRooms: rooms,
loading: false,
price: maxPrice,
maxPrice,
maxSize,
});
}
formatdata = (items) => {
let tempItem = items.map((item) => {
let id = item.sys.id;
let images = item.fields.images.map((image) => image.fields.file.url);
let rooms = { ...item.fields, images, id };
return rooms;
});
return tempItem;
};
getRoom = (slug) => {
let tempRooms = [...this.state.rooms];
const room = tempRooms.find((room) => room.slug === slug);
return room;
};
handleChange = (event) => {
const { target } = event;
const value = event.type === "checkout" ? target.checked : target.value;
const { name } = target;
this.setState(
{
[name]: value,
},
this.filterRooms
);
};
filterRooms = () => {
let {
rooms,
type,
capacity,
price,
minSize,
maxSize,
breakfast,
pets,
} = this.state;
let tempRooms = [...rooms];
if (type !== "all") {
tempRooms = tempRooms.filter((room) => room.type === type);
}
this.setState({
sortedRooms: tempRooms,
});
};
render() {
return (
<RoomContext.Provider
value={{
...this.state,
getRoom: this.getRoom,
handleChange: this.handleChange,
}}
>
{this.props.children}
</RoomContext.Provider>
);
}
}
const RoomConsumer = RoomContext.Consumer;
export function withRoomConsumer(Component) {
return function ConsumerWrapper(props) {
return (
<RoomConsumer>
{(value) => <Component {...props} context={value} />}
</RoomConsumer>
);
};
}
export { RoomProvider, RoomConsumer, RoomContext };
import { createContext, useContext, useEffect, useState } from "react";
import items from "./data";
const RoomContext = createContext();
const useRoomContext = useContext(RoomContext);
const RoomProvider = ({ children }) => {
const [state, setState] = useState({
rooms: [],
sortedRooms: [],
featuredRooms: [],
loading: true,
type: "all",
capacity: 1,
price: 0,
minPrice: 0,
maxPrice: 0,
minSize: 0,
maxSize: 0,
breakfast: false,
pets: false,
});
useEffect(() => {
const rooms = formatdata(items);
const featuredRooms = rooms.filter((room) => room.featured === true);
const maxPrice = Math.max(...rooms.map((item) => item.price));
const maxSize = Math.max(...rooms.map((item) => item.size));
setState((prevState) => {
return {
...prevState,
featuredRooms,
sortedRooms: rooms,
loading: false,
price: maxPrice,
maxPrice,
maxSize,
};
});
}, []);
const formatdata = (items) => {
const tempItem = items.map((item) => {
const id = item.sys.id;
const images = item.fields.images.map((image) => image.fields.file.url);
const rooms = { ...item.fields, images, id };
return rooms;
});
return tempItem;
};
const getRoom = (slug) => {
const tempRooms = [...state.rooms];
const room = tempRooms.find((room) => room.slug === slug);
return room;
};
const handleChange = (event) => {
const { target } = event;
const value = event.type === "checkout" ? target.checked : target.value;
const { name } = target;
setState((prevState) => {
return {
...prevState,
[name]: value,
};
});
filterRooms();
};
const filterRooms = () => {
let { rooms, type } = state;
const tempRooms = [...rooms];
if (type !== "all") {
tempRooms = tempRooms.filter((room) => room.type === type);
}
setState((prevState) => {
return {
...prevState,
sortedRooms: tempRooms,
};
});
};
return (
<RoomContext.Provider value={{
...state,
getRoom,
handleChange
}}>
<Home/>
</RoomContext.Provider>
)
};
export { useRoomContext };
export default RoomProvider;
下面是一个关于如何在 Home 组件中使用上下文的示例:
import { useRoomContest } from "./whatever";
const Home = () => {
const { getRoom, handleChane, ...rest } = useRoomContext();
// here you can access all the date from the context
return (
<div>
</div>
)
};
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.