React,如何将<br/>嵌入jsx表达式中

时间:2019-08-06 20:30:41

标签: javascript reactjs

我要根据给定的变量呈现不同的文本,我只想在h2标签内的特定变量处呈现

我尝试使用正则表达式\ r和\ n(及其组合)进行渲染,但是它不起作用。


render() {

  let {tracker} = this.props, headline;

  switch(tracker){
    case 1:
     headline = 'That is amazing!'
     break;
    case 2:
     headline = 'Too bad.<br />Try again'
     break;
  }

  return(
    <h2>{headline}</h2>
  )
}

4 个答案:

答案 0 :(得分:4)

您的示例的问题在于<br />在字符串中,因此React会将其读取为字符串,并且不会将<br />转换为真实的HTML元素。

自然的解决方案是将字符串连接到实际的JSX <br />

headline = 'Too bad.' + <br /> + 'Try again';

但这不会像我们希望的那样起作用。结果将是Too bad.[object Object]Try again。这是因为JSX只是语法糖,可以编译为React.createElement('br'),并且此函数返回表示React节点的对象。

在第二种情况下,您可以使用React Fragment代替字符串:

render() {

  let {tracker} = this.props, headline;

  switch(tracker){
    case 1:
     headline = 'That is amazing!'
     break;
    case 2:
     headline = <>Too bad.<br />Try again</>
     break;
  }

  return(
    <h2>{headline}</h2>
  )
}

此JSX可以编译成类似React.createElement(React.Fragment, [], ['Too bad.', React.createElement('br'), 'Try again']);的格式,这一点与您的问题不太相关,但我想知道JSX在幕后所做的事很好。

答案 1 :(得分:4)

您似乎想根据父级传递的跟踪器值来渲染不同的标题。

分析

让我们看看下面的代码有什么问题。

render() {

  let {tracker} = this.props, headline;

  switch(tracker){
    case 1:
     headline = 'That is amazing!'
     break;
    case 2:
     headline = 'Too bad.<br />Try again'
     break;
  }

  return(
    <h2>{headline}</h2>
  )
}

首先,this.props, headline的声明似乎很不直观。
让我们将其分为两个。

let headline;
let { tracker } = this.props;

现在,switch检查条件并尝试分配标题值。

  switch(tracker){
    case 1:
     headline = 'That is amazing!'
     break;
    case 2:
     headline = 'Too bad.<br />Try again'
     break;
  }

现在这是有问题的,因为当您返回<h2>{headline}</h2>时,React期望的是element

有效的表达式可以是字符串,数字或另一个JSX元素。

案例1可以,因为它是一个字符串。
但是您遇到情况2的原因是因为<br />是字符串的一部分,因此React将其视为字符串(并尝试对其进行解码)。

那我们该怎么办?

解决方案

通过除去引号并将其包装到元素中,可以将案例2转换为元素。您可以使用任何元素,例如divReact.Fragmenet(<> /)。

  switch(tracker){
    case 1:
     headline = 'That is amazing!'
     break;
    case 2:
     headline = <>Too bad.<br />Try again</>
     // or use "div" or other element.
     // headline = <div>Too bad.<br />Try again</div>
     break;
  }

另一种方法是渲染它dangerously。除非您知道自己在做什么,否则绝对不要这样做。我不会走的太远,因为这可能不是您想要的。

其他提示。

您使用switch使用的代码称为“命令式”代码。 (您指定组件的“工作方式”。)
但是React本质上是声明性的,您可以告诉组件应该做什么。

所以让我们对其进行修复,使其像React一样。

render() {
  // ? tracker is not changed, so declare it as `const`, which is a better practice.
  const {tracker} = this.props

  // You tell React what you want to do.
  // When the tracker value is 1, show 'That's amazing!', 
  // When it's two, show the sympathy.
  return(
    <h2>
      {tracker === 1 && 'That is amazing!}
      {tracker === 2 && <>Too bad.<br />Try again</>}
    </h2>
  )
}

上面的代码做同样的事情,但是您基本上告诉了要做什么,而不是应该如何渲染。

或者您可以走得更远,但我想这足以给小费。

答案 2 :(得分:1)

在以下情况下,当您收到具有可以控制的格式的字符串(即本地化文件或从服务器端消息中提取的字符串)并且希望以换行符输出时,可以使用:

<div style={{whiteSpace: 'pre-wrap'}}>{'Too bad.\nTry again'}</div>

\ n和空格:预先包装即可解决问题。

答案 3 :(得分:0)

在这种情况下,我个人使用Fragment或某些不会引起特殊问题的元素,例如span