Javascript 如何连接从api接收的字符串

Javascript 如何连接从api接收的字符串,javascript,reactjs,api,fetch,Javascript,Reactjs,Api,Fetch,我想突出显示文本元素句子中突出显示元素中的单词。我可以成功地突出显示一个句子,但无法将两个或多个句子连接在一起。我只能显示一个句子,它是用代码突出显示的单词: this.setState({ text: result[0].text, highlight: result[0].highlight, }); 但一次只能说几句话。我想动态地将api中的句子与突出显示的单词连接起来。我尝试将状态设置为text:result[]。text和highlight:result[]。highligh

我想突出显示文本元素句子中突出显示元素中的单词。我可以成功地突出显示一个句子,但无法将两个或多个句子连接在一起。我只能显示一个句子,它是用代码突出显示的单词:

this.setState({
  text: result[0].text,
  highlight: result[0].highlight,
});
但一次只能说几句话。我想动态地将api中的句子与突出显示的单词连接起来。我尝试将状态设置为text:result[]。text和highlight:result[]。highlight,但它给了我错误。如中所示,只有在执行结果[0].text或结果[1].text时,才会得到不同的结果,但我希望动态连接api中的所有句子,假设我将来会有更多的句子

react代码如下所示:

import React, { Component } from "react";
import { render } from "react-dom";

import "./App.css";

const stripChars = word => word.replace(/[\W_]+/g, "");

class App extends Component {
  state = {
    text: "The gun is a dangerous weapon, don't kill anyone",
    highlight: ["gun", "kill"]
    // text: "",
    // highlight: []
  };

  componentDidMount() {
    fetch("https://api.myjson.com/bins/1ep1fh")
      .then(res => res.json())
      .then(result => {
        console.log(result);
        this.setState({
          text: result[0].text,
          highlight: result[0].highlight
        });
      });
  }
  render() {
    const { text, highlight } = this.state;
    const words = text.split(" ");
    return (
      <div>
        {words.map((word, i) => (
          <span key={i}>
            <span
              className={highlight.includes(stripChars(word)) && "highlight"}
            >
              {word}
            </span>
            &nbsp;
          </span>
        ))}
      </div>
    );
  }
}

export default App;

用类似的方法替换代码的中心部分应该可以解决这个问题:

fetch("https://api.myjson.com/bins/1ep1fh")
  .then(res => res.json())
  .then(result => {
    let text = '';
    let highlights = [];

    // This will iterate over every entry in your result
    for(const r of result) {
      // The method will be executed for every entry, called r
      text += r.text;
      highlights.push(...r.highlight);
    }

    this.setState({
      text: text,
      highlight: highlights
    });
  });
}
这与@Dyo的方法非常相似,但应该更有效一点。他创建了整个highlight数组的一个新副本以及要在每次迭代中添加的条目,而在本例中,我们使用array.push方法。这只会添加新值,而不会复制原始值。

您可以使用Array.Map并加入api调用来迭代和展开数组:

  componentDidMount() {
    fetch("https://api.myjson.com/bins/1ep1fh")
      .then(res => res.json())
      .then(result => {
        let texts = result
          .map((el, i) => {
            return el.text;
          })
          .join("");
        let highlights = result
          .map((el, i) => {
            return el.highlight;
          })
          .join("").split(",");
        console.log(highlights);
        this.setState({
          text: texts,
          highlight: highlights
        });
      });
  }

您必须迭代api结果才能连接它们:

  componentDidMount() {
    fetch("https://api.myjson.com/bins/1ep1fh")
      .then(res => res.json())
      .then(result => {
        console.log(result);
        let text = "";
        let highlight = [];
        for (const item of result) {
          text += item.text + '\n';
          highlight = [...highlight, ...item.highlight];
        }
        this.setState({
          text,
          highlight
        });
      });
  }
编辑:一些代码解释

highlight=[…highlight,…item.highlight]

是的,这是数组排列运算符,用于创建一个包含所有要高亮显示的单词的单个数组。对于每个循环迭代,它会传播循环中实际项目突出显示的所有单词,并传播旧单词

您也可以这样做:

for (const word of item.highlight) {
  highlight.push(word);
}
this.setState(prevState => ({
  text: prevState.text + "\n" + text,
  highlight: [...prevState.highlight, ...highlight]
}));
设text=; 让我们突出显示=[]

这只是变量init,这些是新的,我可以用不同的名称命名它们,我应该将它们命名为concatenatedtext和concatenatedHighlights以避免混淆

是的,状态已被擦除,如果要保留初始状态并将其连接起来,可以如下更改设置状态:

for (const word of item.highlight) {
  highlight.push(word);
}
this.setState(prevState => ({
  text: prevState.text + "\n" + text,
  highlight: [...prevState.highlight, ...highlight]
}));

如果API在结果中返回多个元素,则必须迭代结果数组。为此使用for in或for of循环。使用join;否则,两个值之间会有额外的逗号。为什么在第一个值中还要突出显示“a”sentence@MLnewb,因为您使用的包含需要一个数组作为参数,请选中更新的应答。这将覆盖该值,并且状态将有最后一个。@jcubic我明白了。我认为,setState是一种将字符串附加到现有文本的方法。在这种情况下,您必须在这个方法中进行连接。我已经稍微编辑了一下,所以现在应该可以用了。没有任何编辑需要使用text:this.state.text+r。text@jcubic对不起,我在编辑之前已经发布了。编辑现在应该是可见的。现在代码将从输入['foo','bar']->['f','o','o'],['b','a','r']]创建。如果你分散字符串,你将得到一个字符数组,你将它推到另一个数组中。如果你不知道它是如何工作的,请不要使用它。。谢谢你能帮我理解一下吗?这只是一个循环,迭代结果数组,从数组对象中选择每个文本和高亮显示,你能告诉我你不理解的部分吗?你为什么选择让文本和让高亮显示?因为再次使用它,初始状态会被擦除,对吗?因为第一句话应该出现两次,因为我已经将它设置为初始状态,并且它还是api中的第一个元素。这也是您正在使用的排列运算符吗?highlight=[…highlight,…item.highlight];谢谢你的解释。。我可以在突出显示的单词上使用下拉菜单吗?这是一个例子:。。。我想知道在JSFIDLE中编写的react js文件中的onclick方法在哪里demo@MLnewb如果单词像在className中那样高亮显示,您可以有条件地呈现,您可能需要为此创建一个新问题,因为这样的注释很难帮助您。