首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >不更新状态更改的React视图

不更新状态更改的React视图
EN

Stack Overflow用户
提问于 2021-04-05 14:13:59
回答 2查看 307关注 0票数 1

我有一个名单的名字要呈现。列表由搜索输入筛选,但也由gender_id过滤。

问题是,当我更新数组中对象的saved_id时,视图不会改变。我的子组件有一个按钮,如果saved_id是1,输出'Save‘,如果saved_id是2,输出'Remove’。在更新状态后,我可以同时输出‘name’和‘searchFilteredNames’数组,并且都可以得到更新。但是,我使用.map()来呈现列表的const‘性别筛选名称’由于某种原因没有捕捉到更改。知道为什么会这样吗?

父组件(带有名称的表):

代码语言:javascript
运行
复制
export default function Names(props) {
/* Raw list */
const [names, setNames] = useState([]);

/* Search filtered list */
const [searchFilteredNames, setSearchFilteredNames] = useState([...names]);

/* Gender filter */
const [genderFilter, setGenderFilter] = useState(1);

/* Show only names where gender_id is equal to gender filter AND status === 1 */
const genderFilteredNames = searchFilteredNames.filter((name) => {
  return name.status_id === 1 && name.gender_id === genderFilter;
});

/* Get names from Database on render */
useEffect(() => {
  getNames();
}, []);

/* Update search-filtered array on root array update */
useEffect(() => {
  setSearchFilteredNames(names);
}, [names]);

/* Get names */
function getNames() {
  axios.get("http://localhost:3001/select").then((response) => {
    setNames(response.data);
  });
}

/* Update object in array */
function updateSave(id, savedId) {
  // Make copy of original array
  let newNames = [...names];

  // Get index of object to update
  for (var index = 0; index < names.length; index++) if (names[index].id === id) break;

  // Update object value
  newNames[index].saved_id = savedId;

  // Set the state to new copy
  setNames(newNames)
}

/* Render names */
function renderNames() {
  return genderFilteredNames.map((name) => (
    <Name
      key={name.id}
      id={name.id}
      name={name.name}
      saved={name.saved_id}
      gender_id={name.gender_id}
      use={() => handleUse(name.id)}
      save={() => handleSave(name.id)}
    />
  ));
}
...

子组件(单行):

代码语言:javascript
运行
复制
export default function Name(props) {
  const [name, setName] = useState(props.name);
  const [saved, setSaved] = useState(props.saved);
  const useFn = props.use;
  const saveFn = props.save;

  function savedStatus() {
    return saved === 1 ? <>Save</> : <>Remove</>;
  }

  return (
    <>
      <tr>
        <td>{name}</td>
        <td className="actions-2">
          <button className="btn btn-tan" onClick={useFn}>
            <FaRegEdit />
            Use
          </button>

          <button className="btn btn-tan" onClick={saveFn}>
            <GiSaveArrow />
            {savedStatus()}
          </button>
        </td>
      </tr>
    </>
  );
}
EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2021-04-05 20:18:00

我意识到它为什么不起作用..。我在子组件中使用useState作为saved_status,而不是用setState更新它.

这里:

代码语言:javascript
运行
复制
export default function Name(props) {
const [name, setName] = useState(props.name); 
const [saved, setSaved] = useState(props.saved);***** HERE ******

改为:

代码语言:javascript
运行
复制
export default function Name(props) {
const name = props.name;
const saved = props.saved;
票数 0
EN

Stack Overflow用户

发布于 2021-04-05 14:19:42

问题是,您正在直接改变一个状态对象,而不能使用React状态。这里是:

代码语言:javascript
运行
复制
function updateSave(id, savedId) {
  // Make copy of original array
  let newNames = [...names];

  // Get index of object to update
  for (var index = 0; index < names.length; index++) if (names[index].id === id) break;

  // Update object value
  newNames[index].saved_id = savedId; // <========================== *** here

  // Set the state to new copy
  setNames(newNames)
}

相反,您必须在所创建的新数组的元素中设置一个新对象:

代码语言:javascript
运行
复制
function updateSave(id, savedId) {
  // Make copy of original array
  let newNames = [...names];

  // Get index of object to update
  for (var index = 0; index < names.length; index++) if (names[index].id === id) break;

  // Update object value
  newNames[index].saved_id = {...newNames[index], saved_id = savedId}; // *** here

  // Set the state to new copy
  setNames(newNames)
}

现在,React将看到对象与前一个对象不一样,并重新呈现它。

不管值多少钱,我可能会用不同的方式来写这个函数:

代码语言:javascript
运行
复制
function updateSave(id, savedId) {
    const newNames = names.map(name => {
        if (name.id === id) {
            // This is the one we're updating, update it
            return {...name, saved_id = saveId};
        }
        return name; // No change
    })
    setNames(newNames);
}

或者,如果你追求的是超简洁(我真的不喜欢;我更喜欢调试的方便性,而把小型化留给小型化,尽管这个特定的成语在React或其他不变的代码中相当常见),那么:

代码语言:javascript
运行
复制
function updateSave(id, savedId) {
    setNames(names.map(name =>
        name.id === id ? {...name, saved_id: saveId} : name
    ));
}
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/66954422

复制
相关文章

相似问题

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