3 回答

TA貢獻1828條經驗 獲得超3個贊
我的問題的解決方法是它沒有重新渲染,所以它一直落后于整個時間。
在 useEffect 中添加狀態作為依賴項可以解決問題!我希望這可以幫助其他有類似問題的人,以某種方式幫助社區。
import React, { createContext, useState, useEffect } from "react";
import items from "../data";
export const RoomContext = createContext();
const RoomProvider = (props) => {
const [rooms, setRooms] = useState([]);
const [sortedRooms, setSortedRooms] = useState([]);
const [featuredRooms, setFeaturedRooms] = useState([]);
const [loading, setLoading] = useState(true);
const [type, setType] = useState("all");
const [capacity, setCapacity] = useState(1);
const [price, setPrice] = useState(0);
const [minPrice, setMinPrice] = useState(0);
const [maxPrice, setMaxPrice] = useState(0);
const [minSize, setMinSize] = useState(0);
const [maxSize, setMaxSize] = useState(0);
const [breakfast, setBreakfast] = useState(false);
const [pets, setPets] = useState(false);
//call the formatted data
useEffect(() => {
//set rooms
const rooms = formatData(items);
//set the featured rooms
const featuredRooms = rooms.filter((room) => room.featured === true);
//always show the max price as default
const maxPrice = Math.max(...rooms.map((item) => item.price));
//always show the max price as default
const maxSize = Math.max(...rooms.map((item) => item.size));
setRooms(rooms);
setSortedRooms(rooms);
setFeaturedRooms(featuredRooms);
setLoading(false);
setMaxPrice(maxPrice);
setMaxSize(maxSize);
setPrice(maxPrice);
}, [
type,
capacity,
price,
minPrice,
maxPrice,
minSize,
maxSize,
breakfast,
pets,
]);
//format data is getting all the required fields we want to pull from the originl data
const formatData = (items) => {
let tempItems = items.map((item) => {
const id = item.sys.id;
const images = item.fields.images.map((image) => image.fields.file.url);
const room = { ...item.fields, images: images, id: id };
return room;
});
return tempItems;
};
const getRoom = (slug) => {
let tempRooms = [...rooms];
const room = tempRooms.find((room) => room.slug === slug);
return room;
};
const handleChange = (e) => {
const target = e.target;
const value = e.type === "checkbox" ? target.checked : target.value;
const name = e.target.name;
switch (name) {
case "type":
setType(value);
break;
case "capacity":
setCapacity(value);
break;
case "price":
setPrice(value);
break;
case "minPrice":
setMinPrice(value);
break;
case "maxPrice":
setMaxPrice(value);
break;
case "minSize":
setMinSize(value);
break;
case "maxSize":
setMaxSize(value);
break;
case "breakfast":
setBreakfast(value);
break;
case "pets":
setPets(value);
break;
default:
return;
}
console.log(name, value);
};
const filteredRooms = () => {
let initialRooms = [...rooms];
if (type !== "all") {
initialRooms = initialRooms.filter((room) => room.type === type);
}
console.log("room type is", type);
setSortedRooms(initialRooms);
};
return (
<RoomContext.Provider
value={{
rooms,
featuredRooms,
getRoom,
loading,
sortedRooms,
type,
capacity,
price,
minPrice,
maxPrice,
minSize,
maxSize,
breakfast,
pets,
handleChange,
filteredRooms,
}}
>
{props.children}
</RoomContext.Provider>
);
};
export default RoomProvider;

TA貢獻1860條經驗 獲得超8個贊
歡迎來到 SO。您仍然可以編寫this.setState
與 useState 提供的示例類似的代碼。這是一個可快速運行的示例。
圍繞您的項目的答案:
創建一個使用 useContext 的組件,只需加載您需要的值和 handleChange 方法
const Test = () => { const { type, capacity, handleChange } = React.useContext(RoomContext); console.log(type, capacity); return ( <div> <select name="type" onChange={handleChange}> <option value="all">all</option> <option value="another">another</option> <option value="one">one</option> </select> <select name="capacity" onChange={handleChange}> <option value="1">1</option> <option value="50">50</option> <option value="100">100</option> </select> </div> ) };
添加 Test 組件作為 Room Provider 的子組件。
啟動應用程序,您應該會看到它會正常更新
工作可運行示例:
const target = e.target;
const value = e.type === "checkbox" ? target.checked : target.value;
const name = e.target.name;
this.setState({ [name]: value });
const rootEl = document.getElementById('root');
const App = () => {
const [form, setForm] = React.useState({
name: '',
checkbox: false,
});
const handleChange = (e) => {
const target = e.target;
const value = e.type === "checkbox" ? target.checked : target.value;
const name = e.target.name;
setForm(prevState => ({ ...prevState, [name]: value }));
}
return (
<div>
<label>Name</label>
<input type="text" name="name" value={form.name} onChange={handleChange} />
<label>Checkbox</label>
<input type="checkbox" name="checkbox" checked={form.checkbox} onChange={handleChange} />
<pre>{JSON.stringify(form)}</pre>
</div>
)
}
ReactDOM.render(<App />, rootEl);
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.13.0/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.13.0/umd/react-dom.production.min.js"></script>
<div id="root"></div>
這是具有多個 useState 的代碼的運行示例。
const rootEl = document.getElementById('root');
const App = () => {
const [name, setName] = React.useState('');
const [checkbox, setCheckbox] = React.useState(false);
const handleChange = (e) => {
const target = e.target;
const value = e.type === "checkbox" ? target.checked : target.value;
const name = e.target.name;
switch (name) {
case "name":
setName(value);
break;
case "checkbox":
setCheckbox(value);
break;
default:
return;
}
};
return (
<div>
<label>Name</label>
<input type="text" name="name" value={name} onChange={handleChange} />
<label>Checkbox</label>
<input type="checkbox" name="checkbox" checked={checkbox} onChange={handleChange} />
<pre>{JSON.stringify({ name, checkbox })}</pre>
</div>
)
}
ReactDOM.render(<App />, rootEl);
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.13.0/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.13.0/umd/react-dom.production.min.js"></script>
<div id="root"></div>
添加回答
舉報