如何在嵌套的 for of 循环中进行提取

波波

我正在尝试在嵌套的 for of 循环中进行提取。外部 for 循环根据传入的 obj 中找到的属性值写出一个 jsx 无序列表。如果任何属性包含一个数组作为它的值,它会调用一个函数 (buildListFromArray),该函数根据数组的值在父无序列表中写出一个无序列表。该数组的所有元素都将包含一个 url,该 url 仅返回一个 obj 的 json。我想对数组中的每个 url 进行 fetch 以从中获取 name 属性值,以便我可以显示返回的 obj 的 name 属性,而不是该属性包含的原始 url 值。

我会尝试使用 Promises.all() 使用我将构建的一系列承诺,但我认为这不会有所作为。我可以以某种方式使用属性名称返回并插入带有检索值的 jsx,因为每个属性名称都是唯一的。但是我不知道需要在运行时之前写出的嵌套无序列表的属性名称,所以这行不通。下面是代码,希望得到很好的评论

我不一定需要代码,我只是在寻找有关如何处理它的想法。我难住了。

//global incrementing counter used rather than array index to set key 
attribute of list item 
//because other arrays will be built and have the same indexes 
//losing uniqueness for list item key values
let counter = 0;

const buildListFromArray = (listArray, clickFunction) => {
    const output = [];
    for (const item of listArray) {
        counter++;

        //array elements can have a url that returns json but I want to replace the raw url
        //that is displayed by fetching results from that url and displaying it's name property
        //so that users see which name or title the url goes to rather than the url itself
        if (item.includes('https://swapi.co/api/')) {
            fetch(item)
            .then((response) => response.json())
            .then((jsonObj) => {output.push(
                <li className='linkStyle' onClick={clickFunction} key={counter}>
             {jsonObj.results[0].name}
            </li>);})
            .catch((error) => {console.log(error)});
        }
        else {
        output.push(<li key={counter}>{item}</li>);
        }
    }   
    return (<ul>{output}</ul>);
};

buildListArray 从外部 for in 循环调用(最小代码)

cardJsx.push(<li key={prop}><strong>{prop}:</strong> 
{buildListFromArray(value, props.singleCard)}</li>);
嘲笑

当它们完成时,您需要使用 React 状态来跟踪您的 fetch 调用结果。然后,当数据处于可用状态时,您可以使用它来渲染某些内容。您最初使用类似东西的想法Promise.all()是正确的,您只需要更新状态并在需要时重新渲染组件的额外步骤。

这种模式非常普遍,它甚至在 React 文档的官方常见问题解答中有一个条目,你可能应该去阅读它;)

像这样的kiiinda(显然不是100%正确,因为我不知道您的其余代码):

// Note it's now "fetchListFromArray" instead of "build"
// Also note that it needs to be a member function of the class
// so that we can call it with this.fetchListFromArray()
this.fetchListFromArray = (listArray) => {
    // An array of the fetch calls, so we can Promise.all() it later
    const fetches = [];
    for (const item of listArray) {
        if (item.includes('https://swapi.co/api/')) {
            // Here we can push our fetch into the array.
            // Note that the fetch will just resolve to the JSON result
            fetches.push(
                fetch(item)
                .then((response) => response.json());
        }
        else {
            // This will just ensure that our fetch array contains all promises,
            // even for items that don't actually need a fetch
            fetches.push(Promise.resolve(item);
        }
    }

    // Promise.all() will wait for all fetches and then resolve with
    // an array containing all the resulting values. Neat!
    Promise.all(fetches).then(result => {
        // We can store the result in state. This will get updated asynchronously!
        this.setState({fetchResult: result});
    })
};

现在,不是调用fetchListFromArray()in render()(这会中断,因为它有一个setState()调用,你不能在渲染中调用),你可能会这样做,componentDidMount()以便在组件第一次加载时触发初始获取:

componentDidMount() {
    // Not sure where the listArray comes from, maybe props??
    this.fetchListFromArray(this.props.listArray);
}

现在render()你可以用你存储在 state 中的数据做一些事情来做某种动态 JSX 渲染:

render() {
    return (
        <ul>
            {Array.isArray(this.state.fetchResult && this.state.fetchResult.map((ea, i) => {
                // render some kind of JSX. This is just an example...
                <li key={i}>{ea.name}</li>
            })}
        </ul>
    );
}

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章