开发者问题收集

如何从 api 迭代对象列表并将其呈现到 jsx 页面 React 功能组件

2021-03-12
1169

我尝试使用 useEffect 从 api 响应中获取数组项列表,结果我得到了一个对象列表。我想使用 Objects.key() 方法进行转换,但当我迭代它时,值不会打印在视图页面上。响应继续返回来自 api 响应的调用。

API 调用

 export function getServicesById(facility_id) {     
  return axios
        .get(`${baseURL}patients/appointments/1`)
        .then((response) => {
            if(response.status===200){
                // console.log(response.data)
                return response
            }
        }).catch(error => {
            console.log('error', error)
            return error
        });
    }

使用 useEffect 获取响应数据

  useEffect(() => {
    getServicesById()
      .then((res) => {
        setResponseData(res.data);
      })
      .catch((error) => {
        console.log(error);
      });
    // console.log('data is', newResponseData);
  }, [responseData, setResponseData]);

将对象转换为数组项

 const newResponseData = Object.keys(responseData).reduce((array, key) => {
    return [...array, { key: responseData[key] }];
  }, []);

我正在呈现数据的 Jsx 页面

<TableBody>              
  {newResponseData &&
    newResponseData.map((serv, index) => (
    <TableRow key={index}>
       <TableCell align="left" data-label="Action">
           <Field
              name="status"
              component={renderSelectInput}
              variant="outlined"
              size="small"
              className="fileds"
              inputClass="sm-filed"
            >
            <MenuItem selectedValue="progress">
               In progress
             </MenuItem>
             <MenuItem value="closed">
              Closed
             </MenuItem>
            </Field>
            </TableCell>
            <TableCell data-label="Id">{serv.id}</TableCell>
            <TableCell data-label="Patient name">{serv.patient_name}</TableCell>
            <TableCell data-label="Test Name">{serv.test_name}</TableCell>
        </TableRow>
      ))}
   </TableBody>
2个回答

问题

您正在使用效果更新的 useEffect 依赖项:

useEffect(() => {
  getServicesById()
    .then((res) => {
      setResponseData(res.data);
    })
    .catch((error) => {
      console.log(error);
    });
}, [responseData, setResponseData]);

responseData 由效果更新,更新后将触发另一次重新渲染,效果将再次运行。您可能只想在组件安装时获取一次数据。

我看到的另一个潜在问题是 newResponseData 数组仅包含一个 key 键的对象。

const newResponseData = Object.keys(responseData).reduce((array, key) => {
  return [...array, { key: responseData[key] }];
}, []);

但在渲染中,您尝试访问 idpatient_nametest_name 属性。由于 { key: responseData[key] } 不具备上述任何属性,因此这些属性未定义。

解决方案

删除 useEffect 依赖项,以便效果在组件安装时运行一次。由于我还认为您打算计算 responseData 中的对象值数组以将其映射到您的 UI 中,因此您可以在 之前 执行一次此操作将数据发送到状态。

useEffect(() => {
  getServicesById()
    .then((res) => {
      const data = Object.values(res.data)
      setResponseData(data);
    })
    .catch((error) => {
      console.log(error);
    });
}, []);

然后只需映射您的 responseData 状态:

<TableBody>              
  {responseData && responseData.map((serv, index) => (
    <TableRow key={index}>
       <TableCell align="left" data-label="Action">
           <Field
              name="status"
              component={renderSelectInput}
              variant="outlined"
              size="small"
              className="fileds"
              inputClass="sm-filed"
            >
            <MenuItem selectedValue="progress">
               In progress
             </MenuItem>
             <MenuItem value="closed">
              Closed
             </MenuItem>
            </Field>
            </TableCell>
            <TableCell data-label="Id">{serv.id}</TableCell>
            <TableCell data-label="Patient name">{serv.patient_name}</TableCell>
            <TableCell data-label="Test Name">{serv.test_name}</TableCell>
        </TableRow>
      ))}
   </TableBody>
Drew Reese
2021-03-12

除了 Drew Reese 的上述回答之外,请从 useEffect 参数中删除 responseData,因为您在其中使用了 setResponseData ,并且 useEffect 会在每次状态改变时触发:

useEffect(() => {
    getServicesById()
      .then((res) => {
        setResponseData(res.data);
      })
      .catch((error) => {
        console.log(error);
      });
  }, [setResponseData]);
NeERAJ TK
2021-03-12