likes
comments
collection
share

(07)React 入门——④ JSX 语法细节补充 | React 基础理论实操

作者站长头像
站长
· 阅读数 47
转载请注明出处,未经同意,不可修改文章内容。

🔥🔥🔥“前端一万小时”两大明星专栏——“从零基础到轻松就业”、“前端面试刷题”,已于本月大改版,合二为一,干货满满,欢迎点击公众号菜单栏各模块了解。

涉及面试题:
 1. 什么是内联条件表达式?
 2. 为什么 React 使用 className 而不是 class 属性?
 3. 在 React 中如何使用 innerHTML?
 4. 如何在 React 中使用样式?
 5. 如何有条件地渲染组件?
 6. 如何有条件地应用样式类?
 7. 如何使用 React label 元素?
 8. 如何合并多个内联的样式对象?
 9. 如何用 React 漂亮地显示 JSON?
10. 模块化样式文件有什么好处?
11. 是否可以在没有 JSX 的情况下使用 React?

[编号:react_07]

1 className

紧接上篇的代码,我们给 TodoList 增加点样式。

1️⃣首先,我们在 src 目录下增加一个文件 style.css(07)React 入门——④ JSX 语法细节补充 | React 基础理论实操

2️⃣在这个 style.css 里边我们写一些代码:

.input {
  border: 1px solid red;
}

3️⃣然后进入 TodoList 文件,将上边的 CSS 样式引入:

import React, { Component, Fragment } from "react"; 

import "./style.css"; // 3️⃣-①:将当前目录下的 CSS 样式引入;

class TodoList extends Component {
  constructor(props) {
    super(props);

    this.state = {
      inputValue: "", 
      list: []
    };
  }

  render() {
    return(

      <Fragment>
        <div>
      
          {/*
           ❌3️⃣-②:按已有的知识储备,我们会想当然地在这里给 input 标签绑定
           一个名为 input 的 class,以便引入的样式生效!
            */}
          <input 
            class="input"
      
            value={this.state.inputValue}
            onChange={this.handleInputChange.bind(this)}
          />

          <button onClick={this.handleBtnClick.bind(this)}>
            提交
          </button>

        </div>
        <ul>
          {   
            this.state.list.map((item, index)=>{ 
              return( 
                <li
                  key={index}
                  onClick={this.handleItemDelete.bind(this, index)}
                > 
                  {item}
                </li>
              )  
            })
          }
        
        </ul>
      </Fragment>
    )
  }

  handleInputChange(e) {
    this.setState({
      inputValue: e.target.value  
    })
  }

  handleBtnClick() {
    this.setState({
      list: [...this.state.list, this.state.inputValue],  
      inputValue: ""  
    }) 
  }

  handleItemDelete(index) { 
    
    const list = [...this.state.list] 
    
    list.splice(index, 1)  
    this.setState({
      list: list 
    }
    )
  }
}

export default TodoList;

3️⃣-③:保存后,在页面看看效果(样式确实生效了,但控制台却给我们报了“警告”); (07)React 入门——④ JSX 语法细节补充 | React 基础理论实操

❓3️⃣-④:怎么解决上图中的“警告”呢?

答:在 React 里,React 会认为 class 这个“关键字”表示的是 ES6 中的“类”。如果你在 HTML 属性中使用 class ,那么就会和“类” class 产生歧义! 

所以,React 不建议我们把 CSS 中“类选择器”对应的 HTML 属性 class 写成 class ,而要用 className 来代替。

<input 
  className="input"  

  value={this.state.inputValue}
  onChange={this.handleInputChange.bind(this)}
/>

看下效果(样式生效,且不报“警告”): (07)React 入门——④ JSX 语法细节补充 | React 基础理论实操

2 dangerouslySetInnerHTML

❓紧接上边的代码,继续实现一个需求:在页面的 input 框里输入 <h1>hello, Oli.</h1> 并点击“提交”按钮后,我希望在下边的列表项里显示的是“一级标题”样式的 hello, Oli. ,而不是 <h1>hello, Oli.</h1>

目前的代码效果为: (07)React 入门——④ JSX 语法细节补充 | React 基础理论实操

答:

import React, { Component, Fragment } from "react"; 

import "./style.css"; 

class TodoList extends Component {
  constructor(props) {
    super(props);

    this.state = {
      inputValue: "", 
      list: []
    };
  }

  render() {
    return(

      <Fragment>
        <div>
          <input 
            className="input"
      
            value={this.state.inputValue}
            onChange={this.handleInputChange.bind(this)}
          />

          <button onClick={this.handleBtnClick.bind(this)}>
            提交
          </button>

        </div>
        <ul>
          {
            this.state.list.map((item, index)=>{ 
              return( 
                <li 
                  key={index} 
                  onClick={this.handleItemDelete.bind(this, index)}
                  
                  
                  dangerouslySetInnerHTML={{__html: item}}
                >    
                
                  {/*
                  {item}  
                   2️⃣既然 item 写到上边去了,
                   那 li 标签中间的这个 item 就应该删掉了!
                    */}

                </li>

                /*
                1️⃣在“JSX 语法”里边,想要某些内容不自动“转义”,
                我们需要“危险地设置 li 标签的 innerHTML 属性”——dangerouslySetInnerHTML;
                 */

                /*
                1️⃣-①:就如名字所直译的一样,这种做法是“危险”的。由于不会被转义,
                就意味着有“XSS 攻击”的可能。但若真有这需求,也不得不这么做!
                 */

                // 1️⃣-②:等号的右边是用 {} 包裹的 JS 表达式;

                // 1️⃣-③:由于这里的 JS 表达式是一个“JS 对象”,故又是一个 {} 的包裹形式;

                /*
                1️⃣-④:这个“JS 对象”里边,“属性名”表示——往 li 标签里显示一个 html 这个“属性”,
                写法为 __html;
                “属性值”表示——循环过程中产生的这个 item。
                 */
                    
                
              )  
            })
          }
        
        </ul>
      </Fragment>
    )
  }

  handleInputChange(e) {
    this.setState({
      inputValue: e.target.value  
    })
  }

  handleBtnClick() {
    this.setState({
      list: [...this.state.list, this.state.inputValue],  
      inputValue: ""  
    }) 
  }

  handleItemDelete(index) { 
    
    const list = [...this.state.list] 
    
    list.splice(index, 1)  
    this.setState({
      list: list 
    }
    )
  }
}

export default TodoList;

最终效果: (07)React 入门——④ JSX 语法细节补充 | React 基础理论实操

3 htmlFor

❓紧接以上的代码,我想实现一个需求:在页面的 input 框前边增加一些文字 请输入要进行的事项: ,然后点击这些文字时,鼠标就定位到 input 框里,呈现“输入”状态。

🔗前置知识:《HTML:③ HTML 表单详解》

注释 4:

<label for="username">姓名</label>                                  <!-- 注释4 -->

<input id="username"  type="text" name="username" value="Oliver">  <!-- 注释5 -->
  • label for 是为了给一个 input 输入框前边加上可点击的说明文字;
  • label 里边的 forinput 里边的 id 连用,是为了:正常情况下,我要在这个输入框里边输入的话,我仅仅点击前边的说明文字是没反应的,我必须要点击这个输入框才能进入可输入模式。而这里的 label forid 的连用就可以实现点击输入框前边的输入文字也可以进入输入模式。(注意:有 for 就必须有一个 id)

答:

import React, { Component, Fragment } from "react"; 

import "./style.css"; 

class TodoList extends Component {
  constructor(props) {
    super(props);

    this.state = {
      inputValue: "", 
      list: []
    };
  }

  render() {
    return(

      <Fragment>
        <div>
      
      		<label for="insertArea">请输入要进行的事项:</label>		
      		{/* ❌1️⃣根据前置知识,我们貌似能很快写出满足需求的代码; */}
          <input 
      			id="insertArea"
      
            className="input"
            value={this.state.inputValue}
            onChange={this.handleInputChange.bind(this)}
          />

          <button onClick={this.handleBtnClick.bind(this)}>
            提交
          </button>

        </div>
        <ul>
          {
            this.state.list.map((item, index)=>{ 
              return( 
                <li 
                  key={index} 
                  onClick={this.handleItemDelete.bind(this, index)}
                  dangerouslySetInnerHTML={{__html: item}}
                >    
                </li>
                
              )  
            })
          }
        
        </ul>
      </Fragment>
    )
  }

  handleInputChange(e) {
    this.setState({
      inputValue: e.target.value  
    })
  }

  handleBtnClick() {
    this.setState({
      list: [...this.state.list, this.state.inputValue],  
      inputValue: ""  
    }) 
  }

  handleItemDelete(index) { 
    
    const list = [...this.state.list] 
    
    list.splice(index, 1)  
    this.setState({
      list: list 
    }
    )
  }
}

export default TodoList;

看下页面效果(效果是出来了,但是控制台却给我们报了“警告”): (07)React 入门——④ JSX 语法细节补充 | React 基础理论实操

2️⃣怎么解决这个“警告”呢? 答:同本文的第 1 点一样,在 React 里,React 会认为“关键字” for 表示的是“循环”。如果你在 HTML 属性中使用 for ,那么就会和“循环” for 产生歧义!

故,React 要求我们,如果你想在 <label> 标签里使用属性 for ,你得换种写法—— htmlFor

<label htmlFor="insertArea">请输入要进行的事项:</label>

看下页面效果:

(07)React 入门——④ JSX 语法细节补充 | React 基础理论实操

祝好,qdywxs ♥ you!

转载自:https://juejin.cn/post/7268539701941878819
评论
请登录