在React Component中调用一个函数来改变render()中的css

时间:2018-01-16 21:16:41

标签: reactjs

我在React组件中从Spotify返回一组信息,并且想要查询返回的JSON并突出显示艺术家名称中的原始搜索词。例如,如果您搜索“公共汽车”并且返回的艺术家之一是凯特布什,那么这将在“凯特布什”中突出显示为绿色。目前我正在从render()中调用一个函数。但是,我得到的是:

Kate <span style="color:green">Bus</span>h

如何让render()将HTML作为HTML读取(以便Bus只是绿色)而不是呈现为文本?以下React Component的相关代码:

// Called from within render() to wrap a span around a search term embedded in the artist, album or track name
underlineSearch(displayString) {
    let searchTerm = this.props.searchTerm;

    if (displayString.indexOf(searchTerm) !== -1) {
        displayString = displayString.replace(searchTerm, '<span style="color:green">'+searchTerm+'</span>');
    }
    return displayString;
}

render() {
    return (
        <div className="Track" id="Track">
            <div className="Track-information">
                <h3>{this.underlineSearch(this.props.trackName)}</h3>
                <p>{this.underlineSearch(this.props.artistName)} | {this.underlineSearch(this.props.albumName)}</p>
            </div>
        </div>
    );
}

3 个答案:

答案 0 :(得分:0)

您的<?php // including the database connection file include_once("config_bd.php"); if(isset($_POST['update'])) { $pk_membre = mysqli_real_escape_string($mysqli, $_POST['pk_membre']); $nom_membre = mysqli_real_escape_string($mysqli, $_POST['nom_membre']); $prenom_membre = mysqli_real_escape_string($mysqli, $_POST['prenom_membre']); $dateNaissance_membre = mysqli_real_escape_string($mysqli, $_POST['dateNaissance_membre']); $fk_club = mysqli_real_escape_string($mysqli, $_POST['fk_club']); if(empty($nom_membre) || empty($prenom_membre) || empty($dateNaissance_membre) || empty($fk_club)){ if(empty($nom_membre)) { echo "<font color='red'>Le nom du membre est vide.</font><br/>"; } if(empty($prenom_membre)) { echo "<font color='red'>Le prenom du membre est vide.</font><br/>"; } if(empty($dateNaissance_membre)) { echo "<font color='red'>La date de naissance du membre est vide.</font><br/>"; } if(empty($fk_club)) { echo "<font color='red'>Le fk club est vide.</font><br/>"; } } else { //updating the table $result = mysqli_query($mysqli, "UPDATE membres SET nom_membre='$nom_membre',prenom_membre='$prenom_membre', dateNaissance_membre='$dateNaissance_membre', fk_club='$fk_club' WHERE pk_membre=$pk_membre"); //redirectig to the display page. In our case, it is index.php header("Location: vue_membre.php"); } } //getting id from url $pk_membre = $_GET['pk_membre']; //selecting data associated with this particular id $result = mysqli_query($mysqli, "SELECT * FROM membres WHERE pk_membre=$pk_membre"); while($res = mysqli_fetch_array($result)) { $nom_membre = $res['nom_membre']; $prenom_membre = $res['prenom_membre']; $dateNaissance_membre = $res['dateNaissance_membre']; $fk_club = $res['fk_club']; } // requete pour la liste déroulante $reso = mysqli_query($mysqli,"SELECT pk_club,nom_club FROM clubs"); ?> <html> <head> </head> <meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1"> <title>Palais des Sports</title> <link href="https://fonts.googleapis.com/icon?family=Material+Icons" rel="stylesheet"> <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css"> <link rel="stylesheet" type="text/css" href="style/style1.css"> <body> <div class="bandeau-bleu"> <h2>Palais des Sports</h2> <a href="index.php?logout='1'"><i class="material-icons">&#xe897;</i></a> <a href="welcome.php"><i class="material-icons">&#xE88A;</i></a> </div> <div class="form_encodage"> <a href="vue_membre.php"><h3>Cliquez ici pour afficher les enregistrements</h3></a> <br /> <h4> Editer un enregistrement</h4><br /> <form name="form1" method="post" action="edit_membre.php"> <table border="0"> <tr> <td>Nom du Membre:</td> <td><input type="text" name="nom_membre" value="<?php echo $nom_membre;?>"></td> </tr> <tr> <td>Prenom du Membre:</td> <td><input type="text" name="prenom_membre" value="<?php echo $prenom_membre;?>"></td> </tr> <tr> <td>Date Naissance du Membre:</td> <td><input type="text" name="dateNaissance_membre" value="<?php echo $dateNaissance_membre;?>"></td> <tr> <td>Nom du Club:</td> <td><select name="fk_club"> <option>Choisissez un club</option> <?php while($data = mysqli_fetch_array($reso)) { ?> <option value="<?php echo $data['pk_club']?>"><?php echo $data['nom_club']?></option> <?php } ?> </select></td> </tr> </td></tr> <td><input type="submit" name="update" class="bouton_bleu" value="Update"></td> <td><input type="hidden" name="pk_membre" value=<?php echo $_GET['pk_membre'];?>></td> </tr> </table> </form> </div> </body> </html> 函数需要返回React Elements,但现在它返回一个字符串。您可以使用Fragment使其正常工作:

underlineSearch

答案 1 :(得分:0)

为了使您的解决方案更具可重用性,您可以制作underlineSearch并使用您的样式包装,以突出显示为2个单独的组件。更重要的是,您可以使用searchTerm搜索regex的多个匹配项。找到了类似的SO问题here。我根据你的需要略微调整了其中一个答案,但所有功劳都归功于this惊人而又简洁的解决方案,用于突出显示较长文本中字符串的匹配。这是代码:

const Match = ({ children }) => (
  <span style={{'color':'green'}}>{children}</span>
);

const HighlightMatches = ({ text, searchTerm }) => {
  let keyCount = 0;

  let splits = text.split(new RegExp(`\\b${searchTerm}\\b`, 'ig'));
  let matches = text.match(new RegExp(`\\b${searchTerm}\\b`, 'ig'));
  let result = [];

  for (let i = 0; i < splits.length; ++i) {
    result.push(splits[i]);
    if (i < splits.length - 1) {
      result.push(<Match key={++keyCount}>{matches[i]}</Match>);
    }
  }

  return (
    <p>{result}</p>
  );
};

然后在您渲染所有内容的主要组件中,您可以执行此操作:

render() {
   <div className="Track" id="Track">
      <div className="Track-information">
        <h3>
          <HighlightMatches text={this.props.trackName} searchTerm={this.props.searchTerm}/>
        </h3>
        <p>
          <HighlightMatches text={this.props.artistName} searchTerm={this.props.searchTerm} /> |
          <HighlightMatches text={this.props.albumName} searchTerm={this.props.searchTerm} />
      </div>
    </div>
}

对我而言,这似乎是解决问题的最类似react的方法:)

答案 2 :(得分:0)

虽然您可以使用dangerouslySetInnerHTML(),但顾名思义它非常危险,因为它容易受到XSS攻击,例如:

{artist: "Kate Bush<script> giveMeAllYourCookies()</script>"}

您可以将displayString拆分为数组并进行渲染。

请注意,我underlineSearch的实施有漏洞,如果有多个匹配则无效。

&#13;
&#13;
class Main extends React.Component {
  underlineSearch(displayString) {
    let searchTerm = this.props.searchTerm;
    var index = 0;
    var results = [];
    var offset = 0;
    while(true) {
      const index = displayString.indexOf(searchTerm, offset);
      if(index < 0) {
        results.push(<span>{displayString.substr(offset)}</span>);
        break;
      }
      results.push(<span> {displayString.substr(offset, index)}</span>);
      results.push(<strong style={{color: 'green'}}> {displayString.substr(index, searchTerm.length)}</strong>);
      offset = index + searchTerm.length;
    }
    return results;
  }
  
  render() {
    return <div>
                <h3>{this.underlineSearch(this.props.trackName)}</h3>
                <p>{this.underlineSearch(this.props.artistName)} | {this.underlineSearch(this.props.albumName)}</p>

    </div>
  }

}

ReactDOM.render(<Main
  trackName="Magic Buses"
  artistName="Kate Bush"
  albumName="Kate Bush Alubm"
  searchTerm="Bus"
/>, document.getElementById('main'))
&#13;
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>

<div id='main'></div>
&#13;
&#13;
&#13;