React 学习笔记 day 2

本文详细介绍了React组件的三大核心属性:state、props和refs。state是组件的状态,用于驱动组件的重新渲染;props是组件接收的外部属性,用于传递数据;refs提供对组件内部DOM元素或实例的引用,便于直接操作。文章通过示例代码演示了这三个属性的使用方法和注意事项,包括如何更新state、传递props以及使用不同方式创建和使用refs。

组件实例的三大核心属性

注:只有类式组件才有该核心属性,函数式组件没有

state

理解

  • state是组件对象最重要的属性,值是对象(可以包含多个key-value的组合)
  • 组件被称为“状态机”,通过更新组件的state来更新对应的页面显示(重新渲染组件)

示例 

<div id="test"></div>

<script type="text/babel">
    // 1.创建组件
    class Weather extends React.Component{
        //构造器只调用一次
        constructor(props){
            super(props)
            //初始化状态
            this.state = {isHot:false}
            //解决changeWeather中this指向问题
            this.changeWeather = this.changeWeather.bind(this)
        }
        //render调用 1+n 次 1是初始化的那次,n是状态更新的次数 
        render(){
            //读取状态
            const {isHot} = this.state
            return <h1 onClick={this.changeWeather}>今天天气很{isHot ? '炎热' : '凉爽'}</h1>
        }
        
        //changeWeather点几次调几次
        changeWeather(){
            //changeWeather放在哪里?——Weather的原型对象上,供实例使用
            //由于changeWeather是作为onClick的回调,所以不是通过实例调用的,是直接调用
            //类中的方法默认开启了局部的严格模式,所以changeWeather中的this为undefined
            //获取原来的isHot值
            const isHot = this.state.isHot 
            //注:状态不可直接更改,必须通过setState进行更新,且更新是一种合并,不是替换
            this.setState({isHot:!isHot})
        }
    }
    // 2.渲染组件到页面
    ReactDOM.render(<Weather/>, document.getElementById('test'))
</script>

注意点:

  1. render()中 return<h1>中的 onClick 第三个字母为大写
  2. onClick = changeWeather() 这种写法是错误的,正确写法为 onClick = {changeWeather},将changeWeather作为onClick的回调函数
  3. 相同背景颜色处的名称必须一致
  4. 修改状态:this.state.isHot = !isHot (此写法为直接更改,react不支持直接更改,需通过调用React.Component中的setState进行修改)

强烈注意

  • 组件中的 render 方法中的 this 为组件实例对象
  • 组件自定义的方法中 this 为 undefined ,解决方法:强制绑定 this:通过函数对象的 bind();箭头函数
  • 状态数据,不能直接修改或更新

props

理解

  • 每个组件对象都会有props (properties的简写) 属性 

  • 组件标签的所有属性都保存在props中

示例 

<div id="test1"></div>
<div id="test2"></div>
<div id="test3"></div>

<script type="text/babel">
    //创建组件
    class Person extends React.Component{
        //对标签属性进行类型、必要性的限制
        //PropTypes需要引入prop-type.js
        static propTypes = {
            name:PropTypes.string.isRequired,
            age:PropTypes.number,
            sex:PropTypes.string,
            speak:PropTypes.func,
        }
        //指定默认标签属性值
        static defaultProps = {
            sex: '男',
            age: 18
        }
        render(){
            const {name,age,sex} = this.props
            return(
                <ul>
                    <li>姓名:{name}</li>
                    <li>性别:{sex}</li>
                    <li>年龄:{age+1}</li>
                </ul>
            )
        }
    }
    //渲染组件到页面
    ReactDOM.render(<Person name="jerry" speak={speak} />, document.getElementById("test1"))
    ReactDOM.render(<Person name="tom" age={18} sex="女" />, document.getElementById("test2"))
    const p = {name:"老刘", age:18, sex:"女"}
    ReactDOM.render(<Person {...p}/>, document.getElementById("test3"))
    function speak(){
        console.log('我说话了');
    }
</script>

注意点:

  1. 标签属性可使用 展开表达式 进行批量传递
  2.  函数式组件可以使用 props

作用

  •  通过标签属性从组件外向组件内传递变化的数据

  • 注意:组件内部不要修改props数据

refs

字符串形式的ref

<div id="test"></div>

<script type="text/babel">
    class Demo extends React.Component{
        showData = ()=>{
            const {input1} = this.refs
            alert(input1.value)
        }
        showData2 = ()=>{
            const {input2} = this.refs
            alert(input2.value)
        }
        render(){
            return(
                <div>
                    <input ref="input1" type="text" placeholder="点击按钮提示数据"/>&nbsp;
                    <button onClick={this.showData}>点我提示左侧的数据</button>&nbsp;
                    <input ref="input2" onBlur={this.showData2} type="text" placeholder="失去焦点提示数据"/>
                </div>
            )
        }
    }
    ReactDOM.render(<Demo a="1" b="2"/>, document.getElementById('test'))
</script>

回调形式的ref

<div id="test"></div>

<script type="text/babel">
    class Demo extends React.Component{
        showData = ()=>{
            const {input1} = this
            alert(input1.value)
        }
        showData2 = ()=>{
            const {input2} = this
            alert(input2.value)
        }
        render(){
            return(
                <div>
                    <input ref={c => this.input1 = c} type="text" placeholder="点击按钮提示数据"/>&nbsp;
                    <button onClick={this.showData}>点我提示左侧的数据</button>&nbsp;
                    <input ref={c => this.input2 = c} onBlur={this.showData2} type="text" placeholder="失去焦点提示数据"/>
                </div>
            )
        }
    }
    ReactDOM.render(<Demo a="1" b="2"/>, document.getElementById('test'))
</script>

createRef的使用

<div id="test"></div>

<script type="text/babel">
    class Demo extends React.Component{
        myRef = React.createRef()
        myRef2 = React.createRef()
        showData = ()=>{
            alert(this.myRef.current.value)
        }
        showData2 = ()=>{
            alert(this.myRef2.current.value)
        }
        render(){
            return(
                <div>
                    <input ref={this.myRef} type="text" placeholder="点击按钮提示数据"/>&nbsp;
                    <button onClick={this.showData}>点我提示左侧的数据</button>&nbsp;
                    <input ref={this.myRef2} onBlur={this.showData2} type="text" placeholder="失去焦点提示数据"/>
                </div>
            )
        }
    }
    ReactDOM.render(<Demo a="1" b="2"/>, document.getElementById('test'))
</script>

事件处理

  1. 通过onXxx属性指定事件处理函数(注意大小写):React使用的是自定义(合成)事件,而不是使用的原生DOM事件——为了更好的兼容性;React中的事件是通过事件委托方式处理的(委托给组件最外层的元素)——为了高效
  2. 通过event.target得到发生事件的DOM元素对象 ——不要过度使用ref

学习视频地址:尚硅谷React教程(2022加更,B站超火react教程)_哔哩哔哩_bilibili 

基于模拟退火的计算器 在线运行 访问run.bcjh.xyz。 先展示下效果 https://pan.quark.cn/s/cc95c98c3760 参见此仓库。 使用方法(本地安装包) 前往Releases · hjenryin/BCJH-Metropolis下载最新 ,解压后输入游戏内校验码即可使用。 配置厨具 已在2.0.0弃用。 直接使用白菜菊花代码,保留高级厨具,新手池厨具可变。 更改迭代次数 如有需要,可以更改 中39行的数字来设置迭代次数。 本地编译 如果在windows平台,需要使用MSBuild编译,并将 改为ANSI编码。 如有条件,强烈建议这种本地运行(运行可加速、可多次重复)。 在 下运行 ,是游戏中的白菜菊花校验码。 编译、运行: - 在根目录新建 文件夹并 至build - - 使用 (linux) 或 (windows) 运行。 最后在命令行就可以得到输出结果了! (注意顺序)(得到厨师-技法,表示对应新手池厨具) 注:linux下不支持多任务选择 云端编译已在2.0.0弃用。 局限性 已知的问题: - 无法得到最优解! 只能得到一个比较好的解,有助于开阔思路。 - 无法选择菜品数量(默认拉满)。 可能有一定门槛。 (这可能有助于防止这类辅助工具的滥用导致分数膨胀? )(你问我为什么不用其他语言写? python一个晚上就写好了,结果因为有涉及json读写很多类型没法推断,jit用不了,算这个太慢了,所以就用c++写了) 工作原理 采用两层模拟退火来最大化总能量。 第一层为三个厨师,其能量用第二层模拟退火来估计。 也就是说,这套方法理论上也能算厨神(只要能够在非常快的时间内,算出一个厨神面板的得分),但是加上厨神的食材限制工作量有点大……以后再说吧。 (...
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Cancri e

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值