react 学习

创建项目

  1. create-react-app my-app 创建项目
  2. cd my-app
  3. npm start 启动
  4. npm run build 打包
  5. npm test 测试
  6. npm run eject 暴露react配置(不可逆转)

第一阶段

组建的render方法

注意 必须要用一个外层元素把内容进行包裹:

render () {
  return (
    <div>
      <div>{word}</div>
    </div>
  )
}
表达式插入
render () {
  const word = 'hello word'
  return (
    <div>
      <div>{word}</div>
    </div>
  )
}
函数表达式返回
render () {
  return (
    <div>
      <div>{(function () { return 'hello word'})()}</div>
    </div>
  )
}

<font color="red">注意:</font> {} 内可以放任何 JavaScript 的代码,包括变量、表达式计算、函数执行等等。

表达式也可以用在标签的属性上
render () {
  const className = 'hello'
  return (
    <div className={className}>
      <h1>React</h1>
    </div>
  )
}

同时也支持条件判断,双目,三目这些一些

组件的组合、嵌套和组件树

class Main extends Component {
  render() {
    return (
      <div>这是content</div>
    )
  }
}

class Footer extends Component {
  render() {
    return (
      <div>这是尾部</div>
    )
  }
}

class App extends Component {
  
  render() {
    return (
      <div>
        <Main />  
        <Footer />
      </div>
    )
  }
}

事件监听

class Header extends Component {
  handleClickTitle(e) {
    console.log('test click')
    console.log('e', e.target)
  }

  render() {
    return (
      <div>
        <Title />
        <h2 onClick={this.handleClickTitle}>这是头部</h2>
      </div>
    )
  }
}

如果你想在事件函数当中使用当前的实例,你需要手动地将实例方法 bind 到当前实例上再传入给 React.js。

class Main extends Component {
  handleClickContent(word, e) {
    console.log(this, word)
  }

  render() {

    // 绑定this
    return (
      <div onClick={this.handleClickContent.bind(this, 'hello')}>这是content</div>
    )
  }
}

组件的 state 和 setState

class Footer extends Component {

  constructor() {
    super()
    this.state = {
      support: false,
    }
  }

  handleClick() {
    this.setState({
      support: !this.state.support
    })

    // setState 的时候,React.js 并不会马上修改 state。而是把这个对象放到一个更新队列里面,稍后才会从队列当中把新的状态提取出来合并到 state 当中
    console.log(this.state.support)
  }

  // setState 第二种使用方式
  add() {
    // this.setState({count : 0})   // this.state.count 还是 undefined
    // this.setState({count : this.state.count + 1})  // undefined + 1 null


    this.setState((prevState) => {
      return {count: 0}
    })

    this.setState((prevState) => {
      return {count: prevState.count + 1}
    })

    this.setState((prevState) => {
      console.log(prevState.count)
      return { count: prevState.count + 2 } // 上一个 setState 的返回是 count 为 1,当前返回 3
    })
  }

  render() {

    return (
      <div>
        这是尾部
        <button onClick={this.handleClick.bind(this)}>
          {this.state.support ? '取消' : '支持'}
        </button>

        <button onClick={this.add.bind(this)}>+1</button>
        
      </div>
    )
  }
}

配置组件的 props

class Support extends Component {

  // 和vue一样, props不可变
  // 默认配置 defaultProps
  static defaultProps = {
    left: '支持',
    right: '反对'
  }

  constructor() {

    
    super()
    this.state = {
    }
  }

  render () {
    return (
      <div className="support">
        <button>{this.props.left}</button>
        <button>{this.props.right}</button>
      </div>
    )
  }
}

同时也可以往props里面传入函数

列表渲染


const users = [
  { username: 'Jerry', age: 21, gender: 'male' },
  { username: 'Tony', age: 22, gender: 'male' },
  { username: 'Lily', age: 19, gender: 'female' },
  { username: 'Lucy', age: 20, gender: 'female' }
]

class User extends Component {
  render() {
    const {user} = this.props
    return (
      <div>
        <div>姓名:{user.username}</div>
        <div>年龄:{user.age}</div>
        <div>性别:{user.gender}</div>
      </div>
    )
  }
}

class Main extends Component {

  render() {

    // 绑定this
    return (
      <div>
        {users.map((user, idx) => <User key={idx} user={user} />)}
      </div>
      
    )
  }
}

key 必须是每个元素唯一的标识。一般来说,key 的值可以直接后台数据返回的 id,因为后台的 id 都是唯一的。

向父组件传递数据


// 子组件
class CommentInput extends Component {

  constructor() {
    super()
    this.state = {
      username: '',
      content: ''
    }
  }
  /**
   * React.js 当中必须要用 setState 才能更新组件的内容,
   * 所以我们需要做的就是:监听输入框的 onChange 事件,然后获取到用户输入的内容,
   * 再通过 setState 的方式更新 state 中的 username,这样 input 的内容才会更新
   */

  handleUsernameChange(event) {
    this.setState({
      username: event.target.value
    })
  }

  handleContentChange(event) {
    this.setState({
      content: event.target.value
    })
  }

  handleSubmit() {

    /**
     * CommentInput 如何向 CommentApp 传递的数据?
     * 父组件 CommentApp 只需要通过 props 给子组件 CommentInput 传入一个回调函数。
     * 当用户点击发布按钮的时候,CommentInput 调用 props 中的回调函数并且将 state 传入该函数即可。
     */

     if (this.props.onSubmit) {
       const {username, content} = this.state
       this.props.onSubmit({username, content})
     }

     this.setState({content: ''})

  }

  render() {
    return (
      <div className="comment-input">
        <div className='comment-field'>
          <span className='comment-field-name'>用户名:</span>
          <div className='comment-field-input'>
            <input 
              onChange={this.handleUsernameChange.bind(this)}
              value={this.state.username} />
          </div>
        </div>
        <div className='comment-field'>
          <span className='comment-field-name'>评论内容:</span>
          <div className='comment-field-input'>
            <textarea 
              onChange={this.handleContentChange.bind(this)}
              value={this.state.content} />
          </div>
        </div>
        <div className='comment-field-button'>
          <button onClick={this.handleSubmit.bind(this)}>
            发布
          </button>
        </div>
      </div>
    )
  }
}

父组件接收

class CommentApp extends Component {

  handleSubmitComment (comment) {
    console.log(comment)
  }

  render() {
    return (
      <div className="wrapper">
        <CommentInput 
          onSubmit={this.handleSubmitComment.bind(this)} />
      </div>
    )
  }
}

第二阶段

挂载阶段的组件生命周期

class Header extends Component {
  constructor() {
    super()
    console.log('constructor')
  }

  componentWillMount() {
    console.log('component will mount')
  }

  componentDidMount() {
    console.log('component did mount')
  }

  render() {

    console.log('render')
    return (
      <div>
        <h2>这是头部</h2>
      </div>
    )
  }

  componentWillUnmount() {
    console.log('component will unmount')
  }
}

执行顺序

constructor
component will mount
render
component did mount
class App extends Component {
  constructor() {
    super()
    this.state = {
      isShowHeader: true,
    }
  }

  handleShowOrHide() {
    this.setState({
      isShowHeader: !this.state.isShowHeader
    })
  }
  
  render() {
    return (
      <div>
        <p>时钟</p>
        {this.state.isShowHeader ?  <Header /> : null}
        <button onClick={this.handleShowOrHide.bind(this)}>{this.state.isShowHeader ? '隐藏' : '显示'}</button>
        <Main />  
      </div>
    )
  }
}

当组件销毁的时候会执行componentWillUnmount这个钩子

ref 和 React.js 中的 DOM 操作

class Main extends Component {

  componentDidMount() {
    this.input.focus()
  }

  render() {
    return (
      <input ref={(input) => this.input = input} />
    )
  }
}

这里是拿到input的引用,让input自动获取焦点

props.children 和容器类组件


class Card extends Component {
  render() {
    return (
      <div className="card">
        <div className="card-content">
          {this.props.children}
        </div>
      </div>
    )
  }
}

class App extends Component {
  render() {
    return (
      <div>
        <Card>
        <h2>React.js 小书</h2>
        <div>开源、免费、专业、简单</div>
        订阅:<input />
        </Card>
        <Main />  
      </div>
    )
  }
}

dangerouslySetHTML 和 style 属性

动态的 HTML 内容

class Main extends Component {
  handleClickContent(word, e) {
    console.log(this, word)
  }

  // dangerouslySetInnerHTML 可以让我们设置动态设置元素的 innerHTML
  constructor() {
    super()
    this.state = {
      content: '<h1>hello React</h1>',
      color: 'red'
    }
  }

  render() {

    // 需要把 CSS 属性变成一个对象再传给元素
    return (
      <div style={{fontSize: '20px', color: this.state.color}} dangerouslySetInnerHTML={{__html: this.state.content}}></div>
    )
  }
}

PropTypes 和组件参数验证

先要安装一个 React 提供的第三方库 prop-types

npm install --save prop-types

示例

import PropTypes from 'prop-types'


class Comment extends Component {
  
  // 验证
  static propTypes = {
    comment: PropTypes.object
  }

  render () {
    const { comment } = this.props

    return (
      <div className='comment'>
        <div className='comment-user'>
          <span>{comment.username} </span></div>
        <p>{comment.content}</p>
      </div>
    )
  }
}


class App extends Component {
  
  render() {
    return (
      <div>
        <Comment comment={{username: 'bie', content: '哈哈哈哈'}} />
      </div>
     

    );
  }
}

这时候如果再往里面传入数字,浏览器就会报错.

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
水资源是人类社会的宝贵财富,在生活、工农业生产中是不可缺少的。随着世界人口的增长及工农业生产的发展,需水量也在日益增长,水已经变得比以往任何时候都要珍贵。但是,由于人类的生产和生活,导致水体的污染,水质恶化,使有限的水资源更加紧张。长期以来,油类物质(石油类物质和动植物油)一直是水和土壤中的重要污染源。它不仅对人的身体健康带来极大危害,而且使水质恶化,严重破坏水体生态平衡。因此各国都加强了油类物质对水体和土壤的污染的治理。对于水中油含量的检测,我国处于落后阶段,与国际先进水平存在差距,所以难以满足当今技术水平的要求。为了取得具有代表性的正确数据,使分析数据具有与现代测试技术水平相应的准确性和先进性,不断提高分析成果的可比性和应用效果,检测的方法和仪器是非常重要的。只有保证了这两方面才能保证快速和准确地测量出水中油类污染物含量,以达到保护和治理水污染的目的。开展水中油污染检测方法、技术和检测设备的研究,是提高水污染检测的一条重要措施。通过本课题的研究,探索出一套适合我国国情的水质污染现场检测技术和检测设备,具有广泛的应用前景和科学研究价值。 本课题针对我国水体的油污染,探索一套检测油污染的可行方案和方法,利用非分散红外光度法技术,开发研制具有自主知识产权的适合国情的适于野外便携式的测油仪。利用此仪器,可以检测出被测水样中亚甲基、甲基物质和动植物油脂的污染物含量,为我国众多的环境检测站点监测水体的油污染状况提供依据。
### 内容概要 《计算机试卷1》是一份综合性的计算机基础和应用测试卷,涵盖了计算机硬件、软件、操作系统、网络、多媒体技术等多个领域的知识点。试卷包括单选题和操作应用两大类,单选题部分测试学生对计算机基础知识的掌握,操作应用部分则评估学生对计算机应用软件的实际操作能力。 ### 适用人群 本试卷适用于: - 计算机专业或信息技术相关专业的学生,用于课程学习或考试复习。 - 准备计算机等级考试或职业资格认证的人士,作为实战演练材料。 - 对计算机操作有兴趣的自学者,用于提升个人计算机应用技能。 - 计算机基础教育工作者,作为教学资源或出题参考。 ### 使用场景及目标 1. **学习评估**:作为学校或教育机构对学生计算机基础知识和应用技能的评估工具。 2. **自学测试**:供个人自学者检验自己对计算机知识的掌握程度和操作熟练度。 3. **职业发展**:帮助职场人士通过实际操作练习,提升计算机应用能力,增强工作竞争力。 4. **教学资源**:教师可以用于课堂教学,作为教学内容的补充或学生的课后练习。 5. **竞赛准备**:适合准备计算机相关竞赛的学生,作为强化训练和技能检测的材料。 试卷的目标是通过系统性的题目设计,帮助学生全面复习和巩固计算机基础知识,同时通过实际操作题目,提高学生解决实际问题的能力。通过本试卷的学习与练习,学生将能够更加深入地理解计算机的工作原理,掌握常用软件的使用方法,为未来的学术或职业生涯打下坚实的基础。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值