React基础 状态的修改和状态的不可变性

修改状态

通过 setState 修改状态的写法

  • 语法:this.setState({要修改的部分数据})
  • 作用:修改state 并更新视图
  • 来源:setState() 函数是通过继承来的
  • 注意:setState() 的操作是合并,不会影响没有操作到的数据

 状态的不可变性

不要直接修改数据,而是要产生一份新的数据,然后通过setState() 用新的数据覆盖原来的数据,这么做的其中一个重要原因就是为了性能优化

受控表单组件

能够使用受控组件的方式收集到表单中的数据

受控不受控一般是针对表单来说的,所谓受控表单组件,即表单元素的value 值受到了 React 中(state)的控制(对状态的操作会影响试图,视图的变化又会反映到状态上)

input

  1. 在 state 中添加一个状态,作为表单元素的 value 值(数据影响视图)。

  2. 给表单元素绑定 onChange 事件,将表单元素的值设置为 state 的值(视图影响数据)。

import React from 'react'
​
export default class App extends React.Component {
    state = {
        username: '',
    }
    changeText = (e) => {
        this.setState({
            username: e.target.value,
        })
    }
    render() {
        const { username } = this.state
        return (
            <ul>
                <li>
                    <label htmlFor='username'>用户名</label>
                    <input id='username' type='text' value={username} onChange={this.changeText} />
                </li>
            </ul>
        )
    }
}

textarea

操作方式和 input 框一样。

import React from 'react'
​
export default class App extends React.Component {
    state = {
        content: '',
    }
    changeTextArea = (e) => {
        this.setState({
            content: e.target.value,
        })
    }
    render() {
        const { content } = this.state
        return (
            <ul>
                {/* ... */}
                <li>
                    <label htmlFor='content'>其他信息</label>
                    <textarea id='content' cols='30' rows='10' value={content} onChange={this.changeTextArea}></textarea>
                </li>
            </ul>
        )
    }
}

select

import React from 'react'
​
export default class App extends React.Component {
    state = {
        frame: 'react',
    }
    changeOption = (e) => {
        this.setState({
            frame: e.target.value,
        })
    }
    render() {
        const { frame } = this.state
        return (
            <ul>
                {/* ... */}
                <li>
                    <label htmlFor='frame'>框架</label>
                    <select id='frame' value={frame} onChange={this.changeOption}>
                        <option value='vue'>Vue</option>
                        <option value='react'>React</option>
                        <option value='angular'>Angular</option>
                    </select>
                </li>
            </ul>
        )
    }
}

radio

多个单选按钮,绑定的值可以是一个字符串。

export default class App extends React.Component {
    state = {
        checkedRadio: 'male',
    }
    changeRadio = (e) => {
        this.setState({
            checkedRadio: e.target.value,
        })
    }
    render() {
        const { checkedRadio } = this.state
        return (
            <ul>
                {/* ... */}
                <li>
                    <input id='male' type='radio' value='male' checked={checkedRadio === 'male'} onChange={this.changeRadio} />
                    <label htmlFor='male'>男</label>
                    <input id='female' type='radio' value='female' checked={checkedRadio === 'female'} onChange={this.changeRadio} />
                    <label htmlFor='female'>女</label>
                    <input id='unknow' type='radio' value='unknow' checked={checkedRadio === 'unknow'} onChange={this.changeRadio} />
                    <label htmlFor='unknow'>未知</label>
                </li>
            </ul>
        )
    }
}

checkbox

绑定的值可以是一个数组。

import React from 'react'
​
export default class App extends React.Component {
    state = {
        username: '',
        content: '',
        frame: 'react',
        checkedRadio: 'male',
        checkedFruit: ['apple'],
    }
    changeText = (e) => {
        this.setState({
            username: e.target.value,
        })
    }
    changeTextArea = (e) => {
        this.setState({
            content: e.target.value,
        })
    }
    changeOption = (e) => {
        this.setState({
            frame: e.target.value,
        })
    }
    changeRadio = (e) => {
        this.setState({
            checkedRadio: e.target.value,
        })
    }
    changeCheckBox = (e) => {
        const checkedFruit = [...this.state.checkedFruit]
        const idx = checkedFruit.indexOf(e.target.value)
        if (idx === -1) {
            // 数组中没有找到,说明没有被选中,那就把数据添加到数组,进行选中的操作
            checkedFruit.push(e.target.value)
        } else {
            // 找到了,说明已被选中,通过删除数组中的数据取消选中
            checkedFruit.splice(idx, 1)
        }
        this.setState({
            checkedFruit,
        })
    }
    render() {
        const { username, content, frame, checkedRadio, checkedFruit } = this.state
        return (
            <ul>
                <li>
                    <label htmlFor='username'>用户名</label>
                    <input id='username' type='text' value={username} onChange={this.changeText} />
                </li>
                <li>
                    <label htmlFor='content'>其他信息</label>
                    <textarea id='content' cols='30' rows='10' value={content} onChange={this.changeTextArea}></textarea>
                </li>
                <li>
                    <label htmlFor='frame'>框架</label>
                    <select id='frame' value={frame} onChange={this.changeOption}>
                        <option value='vue'>Vue</option>
                        <option value='react'>React</option>
                        <option value='angular'>Angular</option>
                    </select>
                </li>
                <li>
                    <input id='male' type='radio' value='male' checked={checkedRadio === 'male'} onChange={this.changeRadio} />
                    <label htmlFor='male'>男</label>
                    <input id='female' type='radio' value='female' checked={checkedRadio === 'female'} onChange={this.changeRadio} />
                    <label htmlFor='female'>女</label>
                    <input id='unknow' type='radio' value='unknow' checked={checkedRadio === 'unknow'} onChange={this.changeRadio} />
                    <label htmlFor='unknow'>未知</label>
                </li>
                <li>
                    <input id='apple' type='checkbox' value='apple' checked={checkedFruit.includes('apple')} onChange={this.changeCheckBox} />
                    <label htmlFor='apple'>Apple</label>
                    <input id='orange' type='checkbox' value='orange' checked={checkedFruit.includes('orange')} onChange={this.changeCheckBox} />
                    <label htmlFor='orange'>Orange</label>
                </li>
            </ul>
        )
    }
}

非受控表单组件

非受控组件则是通过操作DOM 的方式来获取数据,表单中的value 并没有和state 中的数据进行绑定

通过React.createRef() 来获取DOM

在input上绑定ref 

 

import React, { Component } from 'react'

export default class App extends Component {
    // Step1
    input = React.createRef()
    handleChange = () => {
        // Step3
        console.log(this.input.current.value)
    }
    render() {
        return (
            <div>
                {/* Step2 */}
                <input ref={this.input} type='text' placeholder='输入内容' onChange={this.handleChange} />
            </div>
        )
    }
}

  • 3
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值