首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何使用.splice()属性?

如何使用.splice()属性?
EN

Stack Overflow用户
提问于 2021-09-25 23:32:14
回答 2查看 2.4K关注 0票数 0

我是Reactjs的新手,在本例中,我试图显示一个操作列表。我只需要显示列表的最后10个操作,并且我正在尝试使用数组上的.splice()来完成这一操作。我试了很多次,但没能成功。我得到了以下错误:

TypeError:列表是不可迭代的。

知道怎么做吗?

到目前为止,这是我的组件代码:

代码语言:javascript
复制
export default function ListOperations() {
  const dispatch = useDispatch();
  // const list = useSelector((state) => state.operations);
  const [list, setList] = React.useState({});

  React.useEffect(async () => {
    try {
      const response = await axios.get("http://localhost:3000/operation");

      dispatch({
        type: "LIST_OPERATIONS",
        list: response.data,
      });
    } catch (e) {
      swal("Error", e.message, "error");
    }
  }, []);

  const currentListCopy = [...list];

  if (currentListCopy >= 10) {
    currentListCopy.splice(10);
    setList(currentListCopy);
  }

  return (
    <div>
      <div>
        <h2>OPERATIONS HISTORY:</h2>
      </div>
      <table>
        <thead>
          <tr>
            <th>ID</th>
            <th>Reason</th>
            <th>Amount</th>
            <th>Date</th>
            <th>Type</th>
          </tr>
        </thead>
        <tbody>
          {list.map((oneOperation) =>
            oneOperation ? (
              <tr key={oneOperation.id}>
                <td>{oneOperation.id}</td>
                <td>{oneOperation.reason}</td>
                <td>{oneOperation.amount}</td>
                <td>{oneOperation.date}</td>
                <td>{oneOperation.type}</td>
              </tr>
            ) : null
          )}
        </tbody>
      </table>
    </div>
  );
}

更新版本:

代码语言:javascript
复制
export default function ListOperations(){
    const dispatch = useDispatch();
    const storeList = useSelector((state) => state.operations);
    const [list, setList] = React.useState([]);

    React.useEffect(async () => {
        try{
            const response = await axios.get('http://localhost:3000/operation');

            dispatch({
                type: 'LIST_OPERATIONS',
                list: response.data
            })

            if(Array.isArray(storeList) && storeList.length){
                const currentListCopy = [...storeList];
                if(currentListCopy.length >= 10){
                    currentListCopy.splice(10);
                    setList(currentListCopy);
                }
            }
        }
        catch(e){
            swal("Error", e.message, "error");
        }
    }, [storeList]);
EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2021-09-26 01:06:37

有几个问题导致了错误,而且如果错误是固定的,那么获取的结果将不会显示在应用程序中。

第1期

代码语言:javascript
复制
const [list, setList] = React.useState({});

在上面的代码中,当您试图使用list is not iterable操作符创建一个state object数组时,您将状态初始化为一个对象,这会导致错误的state object,在下面的代码中。

代码语言:javascript
复制
const currentListCopy = [...list];

Fix

可以通过将list状态初始化为空数组来解决此问题。

代码语言:javascript
复制
const [list, setList] = React.useState({});

第2期

第二个问题是,您在useEffect钩子中分配了一个操作,但没有从存储中获取更新的状态,因为这行// const list = useSelector((state) => state.operations);被注释掉了。由于您也没有从存储中获取任何状态,也没有更新本地状态list,因此您将不会看到映射函数中的任何更改,因为它是空的,即使在API调用中从网络返回了一些数据。

Fix

如果您希望使用存储中的状态来更新本地存储,那么您就必须取消注释这一行// const list = useSelector((state) => state.operations)并将列表重命名为其他内容。

此外,您还需要将splice代码移动到useEffect挂钩,因此,每当list在全局状态中更新时,您的本地状态也会相应更新。

代码语言:javascript
复制
React.useEffect(() => {
    if (Array.isArray(list) && list.length) { // assuming list is the global state and we need to ensure the list is valid array with some indexes in it.
      const currentListCopy = [...list];
      if(currentListCopy.length >= 10) { // as above answer point out
        currentListCopy.splice(10);
        setList(currentListCopy)
      }
    }
 }, [list]); // added list as a dependency to run the hook on any change in the list

此外,正如上面answer所指出的,您应该避免useEffect中的异步函数。

更新

完整代码

代码语言:javascript
复制
export default function ListOperations() {
  const dispatch = useDispatch();
  const storeList = useSelector((state) => state.operations);
  const [list, setList] = React.useState([]);

  React.useEffect(async () => {
    try {
      const response = await axios.get("http://localhost:3000/operation");

      dispatch({
        type: "LIST_OPERATIONS",
        list: response.data,
      });
    } catch (e) {
      swal("Error", e.message, "error");
    }
  }, []);

  React.useEffect(() => {
    if (Array.isArray(storeList) && storeList.length) {
      const currentListCopy = [...storeList];
      if(currentListCopy.length >= 10) {
        currentListCopy.splice(10);
        setList(currentListCopy)
      }
    }
 }, [storeList]);

  return (
    <div>
      <div>
        <h2>OPERATIONS HISTORY:</h2>
      </div>
      <table>
        <thead>
          <tr>
            <th>ID</th>
            <th>Reason</th>
            <th>Amount</th>
            <th>Date</th>
            <th>Type</th>
          </tr>
        </thead>
        <tbody>
          {list.map((oneOperation) =>
            oneOperation ? (
              <tr key={oneOperation.id}>
                <td>{oneOperation.id}</td>
                <td>{oneOperation.reason}</td>
                <td>{oneOperation.amount}</td>
                <td>{oneOperation.date}</td>
                <td>{oneOperation.type}</td>
              </tr>
            ) : null
          )}
        </tbody>
      </table>
    </div>
  );
}

票数 1
EN

Stack Overflow用户

发布于 2021-09-25 23:41:56

代码语言:javascript
复制
if(currentListCopy >= 10){
    currentListCopy.splice(10);
    setList(currentListCopy)
}

你错过了“长度”:

代码语言:javascript
复制
if(currentListCopy.length >= 10){
    currentListCopy.splice(10);
    setList(currentListCopy)
} 

此外,你不应该在useEffect https://dev.to/danialdezfouli/what-s-wrong-with-the-async-function-in-useeffect-4jne中使用承诺

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

https://stackoverflow.com/questions/69330773

复制
相关文章

相似问题

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