首页 > 解决方案 > 从功能性反应组件中的 JSON 响应中获取一个特定值并将其设置为选择选项

问题描述

我对 React 很陌生,我有一个选择框,我想用 API 中的数据填充它。API 请求传递该特定用户的 ID,API 将相应的地址返回给该用户。我需要稍后动态设置 ID,但这不是我目前面临的问题;JSON 响应很好,可以通过 JSON 对象进行解析并将所有键值对记录到控制台;但是,在尝试将一个特定的键值对(包含用户地址的键值对)设置为选择框中的选项时,我遇到了麻烦。我编写的函数映射了所有数据并仅返回一个特定的键值对,但它不断迭代 JSON 对象并因此冻结整个应用程序;返回的地址应设置为选择框中的默认选项,

肯定有更好的方法可以做到这一点,但我不知道如何,所以任何提示或帮助将不胜感激,在此先感谢!

代码如下:

import React, {Component, useContext, useEffect, useRef, useState} from 'react';
import "./formstyles.css";

//i18n
import {withNamespaces} from 'react-i18next';

//Import Breadcrumb

import { withRouter } from "react-router-dom";
import classnames from "classnames";
import EmployeesList from "../../pages/Employees/employees-list";
import EmployeeIdComponent from "./EmployeeId";

import EmployeeId from "./EmployeeId";


const SelectComponent = (props) => {


    const [loading, setLoading] = React.useState(true);
    const [error, setError] = React.useState('');
    const [data, setData] = React.useState([]);
    const [mappedArr, setMappedArr] = React.useState([]);
    const [formattedaddress, setAddress] = useState([])

// 下面的函数返回需要的数据

    let usersWithName = Object.keys(data).map(function(key) {
        JSON.stringify(data);
        let newArr = Object.keys(data);
        let mappedArr = newArr.map(function (i) {
            return [i, data[i]];
        })
        let formattedaddress = mappedArr[18];
        return formattedaddress
    });

//这个效果将整个函数设置为选项值

    useEffect(() => {
        setAddress(

        usersWithName
        );
    });

//下面的效果用用户的ID获取数据并返回 //整个对象

    useEffect(() => {
        setLoading(true);
        fetch('http://tpservice:8888/api/v1/address/d472faec-4316-4040-a2cb-63cb99b5bed1')
            .then((response) => response.json())
            .then((data) => {
                setLoading(false);
                setData(data);
            })

            .catch((e) => {
                setLoading(false);
                setError('fetch failed');
            });
    }, []);

    if (loading) {
        return <p>loading..</p>;
    }

    if (error !== '') {
        return <p>ERROR: {error}</p>;
    }

    return (
        <React.Fragment>
           <div className="clearfix">
                <div className="float-left">
                    <div className="input-group input-group-sm">
                        <div className="input-group-append">
                            <label className="input-group-text">Adresse</label>
                        </div>
                        <select className="custom-select custom-select-sm">
                            <option value="1">{formattedaddress}</option>
                            <option value="2">Adresse 2</option>
                            <option value="3">Adresse 3</option>
                            <option value="4">Adresse 4</option>
                        </select>
                    </div>
                </div>
            </div>
        </React.Fragment>
    );



}
export default withRouter(withNamespaces()(SelectComponent));;

标签: javascriptjsonreactjscomponentsresponse

解决方案


首先,我没有看到 useEffect 的依赖数组???在哪里调用 setAddress,usersWithName - 你得到的行为的主要嫌疑人。

第二件事我建议在自定义钩子中导出请求方法,而不是可以在组件中使用的 useEffect,例如 const {data, loading, error} = useRequest()。它使您的组件没有乱码,并且钩子是可重复使用的。

第三,我相信你想要做的是用这个方法 usersWithName 改变响应对象,我会再次将它实现为一个单独的辅助函数,并在钩子中调用它(如果不可重用)或者只是在你想访问变异的价值观。或者您可以使用 useMemo 来存储您的映射数组,并在每次响应更改时重新计算值。

跟进:

钩子.js

const useReqest = ({ requestUrl }) = {
  const [data, setData] = useState();
  const [loading, setLoading] = useState();
  const [error, setError] = useState();

  useEffect(() => {
     fetch(...)
     .then((response) => setData(yourMutationFunction(JSON.parse(response))))
     .catch((e) => setError(e))
  }, [requestUrl])

  return {data, loading, error};
}

您可以在组件中使用它,例如:

// Note this hook is execited everytime requestUrl changes or is initialised
const { data, loading, error } = useRequest({requestUrl: 'someUrl'})

尝试改进这个钩子并完成第三部分!


推荐阅读