为了账号安全,请及时绑定邮箱和手机立即绑定

我的状态没有使用 React Hooks 更新

我的状态没有使用 React Hooks 更新

蝴蝶不菲 2022-12-22 11:41:45
我有一个在更改时触发的事件。此事件检查哪个过滤器已更改,然后相应地更新状态。如果我不使用反应钩子,我会去做这样的事情 -const target = e.target;const value = e.type === "checkbox" ? target.checked : target.value;const name = e.target.name;    this.setState({ [name]: value });如您所见,我可以使用更新状态名称,[name]但由于我使用的是反应钩子,所以我无法使用上面的内容。相反,我得到了这个 -  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 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;      default:        return;    }  };由于某种原因,您在上面看到的内容不起作用。当我触发过滤器时,它会进入案例,因为我已经对此进行了测试,但状态似乎没有更新。名称和值也已记录,它们也很好。我不确定是什么原因造成的,我只是编程的新手,所以任何帮助将不胜感激!
查看完整描述

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;



查看完整回答
反对 回复 2022-12-22
?
桃花长相依

TA贡献1860条经验 获得超8个赞

欢迎来到 SO。您仍然可以编写this.setState与 useState 提供的示例类似的代码。这是一个可快速运行的示例。

围绕您的项目的答案:

  1. 创建一个使用 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>
  )
};
  1. 添加 Test 组件作为 Room Provider 的子组件。

  2. 启动应用程序,您应该会看到它会正常更新

工作可运行示例:

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>


查看完整回答
反对 回复 2022-12-22
?
函数式编程

TA贡献1807条经验 获得超9个赞

你导入 useState 了吗?

import React, {useState} from 'react';


查看完整回答
反对 回复 2022-12-22
  • 3 回答
  • 0 关注
  • 87 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
微信客服

购课补贴
联系客服咨询优惠详情

帮助反馈 APP下载

慕课网APP
您的移动学习伙伴

公众号

扫描二维码
关注慕课网微信公众号