首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >状态更新不影响视图

状态更新不影响视图
EN

Stack Overflow用户
提问于 2021-07-09 07:02:12
回答 4查看 56关注 0票数 1

我正在做一个基本的react项目,在这个项目中,我使用了对象和数组来响应状态,我在这里要做的是把对象推到images数组中,我想在组件中呈现,到目前为止,我搜索了很少的方法来完成它-- array.concatarray.push,我尝试了这两种方法--它正在更新状态,但它对组件没有影响

下面是我尝试过的代码

代码语言:javascript
复制
const [proClrData, setProClrData] = useState([
  { color: "black", price: "", qty: "", images: [] },
  { color: "white", price: "", qty: "", images: [] },
  { color: "red", price: "", qty: "", images: [] }
]);
const addImages = (key) => {
  var obj = { src: "", imgdata: "" };
  proClrData[key].images = proClrData[key].images.concat(obj);
  console.log(proClrData);
 };

下面是组件代码

代码语言:javascript
复制
 {proClrData.length >= 1 &&
    proClrData?.map((clr, key) => {
      return (
        <div key={key}>
          <p className="pt-3 ">{clr.color}</p>
          <div className="form-group">
            <input
              label="Price"
              name="price"
              value={clr?.price}
              type="number"
              fullWidth
              required
            />
          </div>
          <div className="form-group pt-3">
            <input
              label="Quantity"
              name="qty"
              value={clr?.qty}
              type="number"
              fullWidth
              required
            />
          </div>
          <div className="text-end pt-3">
            <button
              variant="contained"
              color="primary"
              onClick={() => addImages(key)}
            >
              Add Images
            </button>
          </div>
          {clr?.images?.map((img, imgkey) => {
            return (
              <div className="form-group pt-3" key={imgkey}>
                <input
                  label="Image"
                  name="images"
                  value=""
                  accept="image/*"
                  type="file"
                  fullWidth
                  required
                />
              </div>
            );
          })}
        </div>
      );
    })}

这是工作代码的codeSandbox

EN

回答 4

Stack Overflow用户

回答已采纳

发布于 2021-07-09 07:12:23

问题

您正在更改状态对象,然后而不是更新状态。

代码语言:javascript
复制
const addImages = (key) => {
  var obj = { src: "", imgdata: "" };
  proClrData[key].images = proClrData[key].images.concat(obj); // mutation!!
  console.log(proClrData);
};

解决方案

将状态更新与所需的新图像数据连接到状态。使用功能状态更新从前一个状态进行更新。浅层复制proClrData数组,对于匹配的元素,也可以浅层复制它,因此它是一个新的对象引用,然后浅层复制嵌套的images数组并追加新的对象。

代码语言:javascript
复制
const [proClrData, setProClrData] = useState([
  { color: "black", price: "", qty: "", images: [] },
  { color: "white", price: "", qty: "", images: [] },
  { color: "red", price: "", qty: "", images: [] }
]);

const addImages = (key) => {
  const obj = { src: "", imgdata: "" };
  setProClrData(data => data.map((el, i) => i === key ? {
    ...el,
    images: [...el.images, obj],
  } : el));
};

由于React状态更新是异步处理的,因此您将希望将控制台日志移动到useEffect钩子中,以便在状态更新后记录状态,并在下一次呈现时可用。

代码语言:javascript
复制
useEffect(() => {
  console.log(proClrData);
}, [proClrData]);
票数 1
EN

Stack Overflow用户

发布于 2021-07-09 07:12:14

您必须调用setProClrData函数来更新状态。

请记住,您不能改变状态,而是必须提供一个新的引用(在您的情况下是一个新的数组)并调用更新器函数,否则您的反应将不知道这是应该重新呈现组件。

代码语言:javascript
复制
const [proClrData, setProClrData] = useState([
  { color: "black", price: "", qty: "", images: [] },
  { color: "white", price: "", qty: "", images: [] },
  { color: "red", price: "", qty: "", images: [] }
]);

const addImages = (key) => {
  const img = { src: "", imgdata: "" };
  const newProClrData = proClrData.map((obj, index) => {
    return index !== key ? data : { ...obj, images: [...data.images, img] };
  });
  setProClrData(newProClrData);
 };
票数 1
EN

Stack Overflow用户

发布于 2021-07-09 07:06:03

您应该相应地修改proClrData并使用setProClrData来触发重呈现。

查看文档:https://reactjs.org/docs/hooks-state.html

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/68312545

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档